perf evsel: Remove use_uncore_alias
[platform/kernel/linux-starfive.git] / tools / perf / util / parse-events.y
1 %define api.pure full
2 %parse-param {void *_parse_state}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
5 %locations
6
7 %{
8
9 #define YYDEBUG 1
10
11 #include <fnmatch.h>
12 #include <stdio.h>
13 #include <linux/compiler.h>
14 #include <linux/types.h>
15 #include <linux/zalloc.h>
16 #include "pmu.h"
17 #include "evsel.h"
18 #include "parse-events.h"
19 #include "parse-events-bison.h"
20
21 void parse_events_error(YYLTYPE *loc, void *parse_state, void *scanner, char const *msg);
22
23 #define ABORT_ON(val) \
24 do { \
25         if (val) \
26                 YYABORT; \
27 } while (0)
28
29 static struct list_head* alloc_list(void)
30 {
31         struct list_head *list;
32
33         list = malloc(sizeof(*list));
34         if (!list)
35                 return NULL;
36
37         INIT_LIST_HEAD(list);
38         return list;
39 }
40
41 static void free_list_evsel(struct list_head* list_evsel)
42 {
43         struct evsel *evsel, *tmp;
44
45         list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) {
46                 list_del_init(&evsel->core.node);
47                 evsel__delete(evsel);
48         }
49         free(list_evsel);
50 }
51
52 static void inc_group_count(struct list_head *list,
53                        struct parse_events_state *parse_state)
54 {
55         /* Count groups only have more than 1 members */
56         if (!list_is_last(list->next, list))
57                 parse_state->nr_groups++;
58 }
59
60 %}
61
62 %token PE_START_EVENTS PE_START_TERMS
63 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
64 %token PE_VALUE_SYM_TOOL
65 %token PE_EVENT_NAME
66 %token PE_NAME
67 %token PE_BPF_OBJECT PE_BPF_SOURCE
68 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
69 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
70 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
71 %token PE_ERROR
72 %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_PMU_EVENT_SUF2 PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
73 %token PE_ARRAY_ALL PE_ARRAY_RANGE
74 %token PE_DRV_CFG_TERM
75 %type <num> PE_VALUE
76 %type <num> PE_VALUE_SYM_HW
77 %type <num> PE_VALUE_SYM_SW
78 %type <num> PE_VALUE_SYM_TOOL
79 %type <num> PE_RAW
80 %type <num> PE_TERM
81 %type <num> value_sym
82 %type <str> PE_NAME
83 %type <str> PE_BPF_OBJECT
84 %type <str> PE_BPF_SOURCE
85 %type <str> PE_NAME_CACHE_TYPE
86 %type <str> PE_NAME_CACHE_OP_RESULT
87 %type <str> PE_MODIFIER_EVENT
88 %type <str> PE_MODIFIER_BP
89 %type <str> PE_EVENT_NAME
90 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_PMU_EVENT_SUF2 PE_KERNEL_PMU_EVENT PE_PMU_EVENT_FAKE
91 %type <str> PE_DRV_CFG_TERM
92 %type <str> event_pmu_name
93 %destructor { free ($$); } <str>
94 %type <term> event_term
95 %destructor { parse_events_term__delete ($$); } <term>
96 %type <list_terms> event_config
97 %type <list_terms> opt_event_config
98 %type <list_terms> opt_pmu_config
99 %destructor { parse_events_terms__delete ($$); } <list_terms>
100 %type <list_evsel> event_pmu
101 %type <list_evsel> event_legacy_symbol
102 %type <list_evsel> event_legacy_cache
103 %type <list_evsel> event_legacy_mem
104 %type <list_evsel> event_legacy_tracepoint
105 %type <list_evsel> event_legacy_numeric
106 %type <list_evsel> event_legacy_raw
107 %type <list_evsel> event_bpf_file
108 %type <list_evsel> event_def
109 %type <list_evsel> event_mod
110 %type <list_evsel> event_name
111 %type <list_evsel> event
112 %type <list_evsel> events
113 %type <list_evsel> group_def
114 %type <list_evsel> group
115 %type <list_evsel> groups
116 %destructor { free_list_evsel ($$); } <list_evsel>
117 %type <tracepoint_name> tracepoint_name
118 %destructor { free ($$.sys); free ($$.event); } <tracepoint_name>
119 %type <array> array
120 %type <array> array_term
121 %type <array> array_terms
122 %destructor { free ($$.ranges); } <array>
123
124 %union
125 {
126         char *str;
127         u64 num;
128         struct list_head *list_evsel;
129         struct list_head *list_terms;
130         struct parse_events_term *term;
131         struct tracepoint_name {
132                 char *sys;
133                 char *event;
134         } tracepoint_name;
135         struct parse_events_array array;
136 }
137 %%
138
139 start:
140 PE_START_EVENTS start_events
141 |
142 PE_START_TERMS  start_terms
143
144 start_events: groups
145 {
146         struct parse_events_state *parse_state = _parse_state;
147
148         /* frees $1 */
149         parse_events_update_lists($1, &parse_state->list);
150 }
151
152 groups:
153 groups ',' group
154 {
155         struct list_head *list  = $1;
156         struct list_head *group = $3;
157
158         /* frees $3 */
159         parse_events_update_lists(group, list);
160         $$ = list;
161 }
162 |
163 groups ',' event
164 {
165         struct list_head *list  = $1;
166         struct list_head *event = $3;
167
168         /* frees $3 */
169         parse_events_update_lists(event, list);
170         $$ = list;
171 }
172 |
173 group
174 |
175 event
176
177 group:
178 group_def ':' PE_MODIFIER_EVENT
179 {
180         struct list_head *list = $1;
181         int err;
182
183         err = parse_events__modifier_group(list, $3);
184         free($3);
185         if (err) {
186                 struct parse_events_state *parse_state = _parse_state;
187                 struct parse_events_error *error = parse_state->error;
188
189                 parse_events_error__handle(error, @3.first_column,
190                                            strdup("Bad modifier"), NULL);
191                 free_list_evsel(list);
192                 YYABORT;
193         }
194         $$ = list;
195 }
196 |
197 group_def
198
199 group_def:
200 PE_NAME '{' events '}'
201 {
202         struct list_head *list = $3;
203
204         inc_group_count(list, _parse_state);
205         /* Takes ownership of $1. */
206         parse_events__set_leader($1, list);
207         $$ = list;
208 }
209 |
210 '{' events '}'
211 {
212         struct list_head *list = $2;
213
214         inc_group_count(list, _parse_state);
215         parse_events__set_leader(NULL, list);
216         $$ = list;
217 }
218
219 events:
220 events ',' event
221 {
222         struct list_head *event = $3;
223         struct list_head *list  = $1;
224
225         /* frees $3 */
226         parse_events_update_lists(event, list);
227         $$ = list;
228 }
229 |
230 event
231
232 event: event_mod
233
234 event_mod:
235 event_name PE_MODIFIER_EVENT
236 {
237         struct list_head *list = $1;
238         int err;
239
240         /*
241          * Apply modifier on all events added by single event definition
242          * (there could be more events added for multiple tracepoint
243          * definitions via '*?'.
244          */
245         err = parse_events__modifier_event(list, $2, false);
246         free($2);
247         if (err) {
248                 struct parse_events_state *parse_state = _parse_state;
249                 struct parse_events_error *error = parse_state->error;
250
251                 parse_events_error__handle(error, @2.first_column,
252                                            strdup("Bad modifier"), NULL);
253                 free_list_evsel(list);
254                 YYABORT;
255         }
256         $$ = list;
257 }
258 |
259 event_name
260
261 event_name:
262 PE_EVENT_NAME event_def
263 {
264         int err;
265
266         err = parse_events_name($2, $1);
267         free($1);
268         if (err) {
269                 free_list_evsel($2);
270                 YYABORT;
271         }
272         $$ = $2;
273 }
274 |
275 event_def
276
277 event_def: event_pmu |
278            event_legacy_symbol |
279            event_legacy_cache sep_dc |
280            event_legacy_mem |
281            event_legacy_tracepoint sep_dc |
282            event_legacy_numeric sep_dc |
283            event_legacy_raw sep_dc |
284            event_bpf_file
285
286 event_pmu_name:
287 PE_NAME | PE_PMU_EVENT_PRE
288
289 event_pmu:
290 event_pmu_name opt_pmu_config
291 {
292         struct parse_events_state *parse_state = _parse_state;
293         struct parse_events_error *error = parse_state->error;
294         struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL;
295         char *pattern = NULL;
296
297 #define CLEANUP_YYABORT                                 \
298         do {                                            \
299                 parse_events_terms__delete($2);         \
300                 parse_events_terms__delete(orig_terms); \
301                 free(list);                             \
302                 free($1);                               \
303                 free(pattern);                          \
304                 YYABORT;                                \
305         } while(0)
306
307         if (parse_events_copy_term_list($2, &orig_terms))
308                 CLEANUP_YYABORT;
309
310         if (error)
311                 error->idx = @1.first_column;
312
313         list = alloc_list();
314         if (!list)
315                 CLEANUP_YYABORT;
316         if (parse_events_add_pmu(_parse_state, list, $1, $2, /*auto_merge_stats=*/false)) {
317                 struct perf_pmu *pmu = NULL;
318                 int ok = 0;
319
320                 if (asprintf(&pattern, "%s*", $1) < 0)
321                         CLEANUP_YYABORT;
322
323                 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
324                         char *name = pmu->name;
325
326                         if (!strncmp(name, "uncore_", 7) &&
327                             strncmp($1, "uncore_", 7))
328                                 name += 7;
329                         if (!perf_pmu__match(pattern, name, $1) ||
330                             !perf_pmu__match(pattern, pmu->alias_name, $1)) {
331                                 if (parse_events_copy_term_list(orig_terms, &terms))
332                                         CLEANUP_YYABORT;
333                                 if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms,
334                                                           /*auto_merge_stats=*/true)) {
335                                         ok++;
336                                 }
337                                 parse_events_terms__delete(terms);
338                         }
339                 }
340
341                 if (!ok)
342                         CLEANUP_YYABORT;
343         }
344         parse_events_terms__delete($2);
345         parse_events_terms__delete(orig_terms);
346         free(pattern);
347         free($1);
348         $$ = list;
349 #undef CLEANUP_YYABORT
350 }
351 |
352 PE_KERNEL_PMU_EVENT sep_dc
353 {
354         struct list_head *list;
355         int err;
356
357         err = parse_events_multi_pmu_add(_parse_state, $1, NULL, &list);
358         free($1);
359         if (err < 0)
360                 YYABORT;
361         $$ = list;
362 }
363 |
364 PE_KERNEL_PMU_EVENT opt_pmu_config
365 {
366         struct list_head *list;
367         int err;
368
369         /* frees $2 */
370         err = parse_events_multi_pmu_add(_parse_state, $1, $2, &list);
371         free($1);
372         if (err < 0)
373                 YYABORT;
374         $$ = list;
375 }
376 |
377 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF '-' PE_PMU_EVENT_SUF2 sep_dc
378 {
379         struct list_head *list;
380         char pmu_name[128];
381         snprintf(pmu_name, sizeof(pmu_name), "%s-%s-%s", $1, $3, $5);
382         free($1);
383         free($3);
384         free($5);
385         if (parse_events_multi_pmu_add(_parse_state, pmu_name, NULL, &list) < 0)
386                 YYABORT;
387         $$ = list;
388 }
389 |
390 PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
391 {
392         struct list_head *list;
393         char pmu_name[128];
394
395         snprintf(pmu_name, sizeof(pmu_name), "%s-%s", $1, $3);
396         free($1);
397         free($3);
398         if (parse_events_multi_pmu_add(_parse_state, pmu_name, NULL, &list) < 0)
399                 YYABORT;
400         $$ = list;
401 }
402 |
403 PE_PMU_EVENT_FAKE sep_dc
404 {
405         struct list_head *list;
406         int err;
407
408         list = alloc_list();
409         if (!list)
410                 YYABORT;
411
412         err = parse_events_add_pmu(_parse_state, list, $1, /*head_config=*/NULL,
413                                    /*auto_merge_stats=*/false);
414         free($1);
415         if (err < 0) {
416                 free(list);
417                 YYABORT;
418         }
419         $$ = list;
420 }
421 |
422 PE_PMU_EVENT_FAKE opt_pmu_config
423 {
424         struct list_head *list;
425         int err;
426
427         list = alloc_list();
428         if (!list)
429                 YYABORT;
430
431         err = parse_events_add_pmu(_parse_state, list, $1, $2, /*auto_merge_stats=*/false);
432         free($1);
433         parse_events_terms__delete($2);
434         if (err < 0) {
435                 free(list);
436                 YYABORT;
437         }
438         $$ = list;
439 }
440
441 value_sym:
442 PE_VALUE_SYM_HW
443 |
444 PE_VALUE_SYM_SW
445
446 event_legacy_symbol:
447 value_sym '/' event_config '/'
448 {
449         struct list_head *list;
450         int type = $1 >> 16;
451         int config = $1 & 255;
452         int err;
453
454         list = alloc_list();
455         ABORT_ON(!list);
456         err = parse_events_add_numeric(_parse_state, list, type, config, $3);
457         parse_events_terms__delete($3);
458         if (err) {
459                 free_list_evsel(list);
460                 YYABORT;
461         }
462         $$ = list;
463 }
464 |
465 value_sym sep_slash_slash_dc
466 {
467         struct list_head *list;
468         int type = $1 >> 16;
469         int config = $1 & 255;
470
471         list = alloc_list();
472         ABORT_ON(!list);
473         ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL));
474         $$ = list;
475 }
476 |
477 PE_VALUE_SYM_TOOL sep_slash_slash_dc
478 {
479         struct list_head *list;
480
481         list = alloc_list();
482         ABORT_ON(!list);
483         ABORT_ON(parse_events_add_tool(_parse_state, list, $1));
484         $$ = list;
485 }
486
487 event_legacy_cache:
488 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_event_config
489 {
490         struct parse_events_state *parse_state = _parse_state;
491         struct parse_events_error *error = parse_state->error;
492         struct list_head *list;
493         int err;
494
495         list = alloc_list();
496         ABORT_ON(!list);
497         err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6,
498                                      parse_state);
499         parse_events_terms__delete($6);
500         free($1);
501         free($3);
502         free($5);
503         if (err) {
504                 free_list_evsel(list);
505                 YYABORT;
506         }
507         $$ = list;
508 }
509 |
510 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config
511 {
512         struct parse_events_state *parse_state = _parse_state;
513         struct parse_events_error *error = parse_state->error;
514         struct list_head *list;
515         int err;
516
517         list = alloc_list();
518         ABORT_ON(!list);
519         err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4,
520                                      parse_state);
521         parse_events_terms__delete($4);
522         free($1);
523         free($3);
524         if (err) {
525                 free_list_evsel(list);
526                 YYABORT;
527         }
528         $$ = list;
529 }
530 |
531 PE_NAME_CACHE_TYPE opt_event_config
532 {
533         struct parse_events_state *parse_state = _parse_state;
534         struct parse_events_error *error = parse_state->error;
535         struct list_head *list;
536         int err;
537
538         list = alloc_list();
539         ABORT_ON(!list);
540         err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2,
541                                      parse_state);
542         parse_events_terms__delete($2);
543         free($1);
544         if (err) {
545                 free_list_evsel(list);
546                 YYABORT;
547         }
548         $$ = list;
549 }
550
551 event_legacy_mem:
552 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc
553 {
554         struct parse_events_state *parse_state = _parse_state;
555         struct list_head *list;
556         int err;
557
558         list = alloc_list();
559         ABORT_ON(!list);
560         err = parse_events_add_breakpoint(list, &parse_state->idx,
561                                           $2, $6, $4);
562         free($6);
563         if (err) {
564                 free(list);
565                 YYABORT;
566         }
567         $$ = list;
568 }
569 |
570 PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc
571 {
572         struct parse_events_state *parse_state = _parse_state;
573         struct list_head *list;
574
575         list = alloc_list();
576         ABORT_ON(!list);
577         if (parse_events_add_breakpoint(list, &parse_state->idx,
578                                         $2, NULL, $4)) {
579                 free(list);
580                 YYABORT;
581         }
582         $$ = list;
583 }
584 |
585 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
586 {
587         struct parse_events_state *parse_state = _parse_state;
588         struct list_head *list;
589         int err;
590
591         list = alloc_list();
592         ABORT_ON(!list);
593         err = parse_events_add_breakpoint(list, &parse_state->idx,
594                                           $2, $4, 0);
595         free($4);
596         if (err) {
597                 free(list);
598                 YYABORT;
599         }
600         $$ = list;
601 }
602 |
603 PE_PREFIX_MEM PE_VALUE sep_dc
604 {
605         struct parse_events_state *parse_state = _parse_state;
606         struct list_head *list;
607
608         list = alloc_list();
609         ABORT_ON(!list);
610         if (parse_events_add_breakpoint(list, &parse_state->idx,
611                                         $2, NULL, 0)) {
612                 free(list);
613                 YYABORT;
614         }
615         $$ = list;
616 }
617
618 event_legacy_tracepoint:
619 tracepoint_name opt_event_config
620 {
621         struct parse_events_state *parse_state = _parse_state;
622         struct parse_events_error *error = parse_state->error;
623         struct list_head *list;
624         int err;
625
626         list = alloc_list();
627         ABORT_ON(!list);
628         if (error)
629                 error->idx = @1.first_column;
630
631         err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event,
632                                         error, $2);
633
634         parse_events_terms__delete($2);
635         free($1.sys);
636         free($1.event);
637         if (err) {
638                 free(list);
639                 YYABORT;
640         }
641         $$ = list;
642 }
643
644 tracepoint_name:
645 PE_NAME '-' PE_NAME ':' PE_NAME
646 {
647         struct tracepoint_name tracepoint;
648
649         ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0);
650         tracepoint.event = $5;
651         free($1);
652         free($3);
653         $$ = tracepoint;
654 }
655 |
656 PE_NAME ':' PE_NAME
657 {
658         struct tracepoint_name tracepoint = {$1, $3};
659
660         $$ = tracepoint;
661 }
662
663 event_legacy_numeric:
664 PE_VALUE ':' PE_VALUE opt_event_config
665 {
666         struct list_head *list;
667         int err;
668
669         list = alloc_list();
670         ABORT_ON(!list);
671         err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4);
672         parse_events_terms__delete($4);
673         if (err) {
674                 free(list);
675                 YYABORT;
676         }
677         $$ = list;
678 }
679
680 event_legacy_raw:
681 PE_RAW opt_event_config
682 {
683         struct list_head *list;
684         int err;
685
686         list = alloc_list();
687         ABORT_ON(!list);
688         err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2);
689         parse_events_terms__delete($2);
690         if (err) {
691                 free(list);
692                 YYABORT;
693         }
694         $$ = list;
695 }
696
697 event_bpf_file:
698 PE_BPF_OBJECT opt_event_config
699 {
700         struct parse_events_state *parse_state = _parse_state;
701         struct list_head *list;
702         int err;
703
704         list = alloc_list();
705         ABORT_ON(!list);
706         err = parse_events_load_bpf(parse_state, list, $1, false, $2);
707         parse_events_terms__delete($2);
708         free($1);
709         if (err) {
710                 free(list);
711                 YYABORT;
712         }
713         $$ = list;
714 }
715 |
716 PE_BPF_SOURCE opt_event_config
717 {
718         struct list_head *list;
719         int err;
720
721         list = alloc_list();
722         ABORT_ON(!list);
723         err = parse_events_load_bpf(_parse_state, list, $1, true, $2);
724         parse_events_terms__delete($2);
725         if (err) {
726                 free(list);
727                 YYABORT;
728         }
729         $$ = list;
730 }
731
732 opt_event_config:
733 '/' event_config '/'
734 {
735         $$ = $2;
736 }
737 |
738 '/' '/'
739 {
740         $$ = NULL;
741 }
742 |
743 {
744         $$ = NULL;
745 }
746
747 opt_pmu_config:
748 '/' event_config '/'
749 {
750         $$ = $2;
751 }
752 |
753 '/' '/'
754 {
755         $$ = NULL;
756 }
757
758 start_terms: event_config
759 {
760         struct parse_events_state *parse_state = _parse_state;
761         if (parse_state->terms) {
762                 parse_events_terms__delete ($1);
763                 YYABORT;
764         }
765         parse_state->terms = $1;
766 }
767
768 event_config:
769 event_config ',' event_term
770 {
771         struct list_head *head = $1;
772         struct parse_events_term *term = $3;
773
774         if (!head) {
775                 parse_events_term__delete(term);
776                 YYABORT;
777         }
778         list_add_tail(&term->list, head);
779         $$ = $1;
780 }
781 |
782 event_term
783 {
784         struct list_head *head = malloc(sizeof(*head));
785         struct parse_events_term *term = $1;
786
787         ABORT_ON(!head);
788         INIT_LIST_HEAD(head);
789         list_add_tail(&term->list, head);
790         $$ = head;
791 }
792
793 event_term:
794 PE_RAW
795 {
796         struct parse_events_term *term;
797
798         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_CONFIG,
799                                         NULL, $1, false, &@1, NULL));
800         $$ = term;
801 }
802 |
803 PE_NAME '=' PE_NAME
804 {
805         struct parse_events_term *term;
806
807         if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
808                                         $1, $3, &@1, &@3)) {
809                 free($1);
810                 free($3);
811                 YYABORT;
812         }
813         $$ = term;
814 }
815 |
816 PE_NAME '=' PE_VALUE
817 {
818         struct parse_events_term *term;
819
820         if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
821                                         $1, $3, false, &@1, &@3)) {
822                 free($1);
823                 YYABORT;
824         }
825         $$ = term;
826 }
827 |
828 PE_NAME '=' PE_VALUE_SYM_HW
829 {
830         struct parse_events_term *term;
831         int config = $3 & 255;
832
833         if (parse_events_term__sym_hw(&term, $1, config)) {
834                 free($1);
835                 YYABORT;
836         }
837         $$ = term;
838 }
839 |
840 PE_NAME
841 {
842         struct parse_events_term *term;
843
844         if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
845                                         $1, 1, true, &@1, NULL)) {
846                 free($1);
847                 YYABORT;
848         }
849         $$ = term;
850 }
851 |
852 PE_VALUE_SYM_HW
853 {
854         struct parse_events_term *term;
855         int config = $1 & 255;
856
857         ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
858         $$ = term;
859 }
860 |
861 PE_TERM '=' PE_NAME
862 {
863         struct parse_events_term *term;
864
865         if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) {
866                 free($3);
867                 YYABORT;
868         }
869         $$ = term;
870 }
871 |
872 PE_TERM '=' PE_VALUE
873 {
874         struct parse_events_term *term;
875
876         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3));
877         $$ = term;
878 }
879 |
880 PE_TERM
881 {
882         struct parse_events_term *term;
883
884         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL));
885         $$ = term;
886 }
887 |
888 PE_NAME array '=' PE_NAME
889 {
890         struct parse_events_term *term;
891
892         if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
893                                         $1, $4, &@1, &@4)) {
894                 free($1);
895                 free($4);
896                 free($2.ranges);
897                 YYABORT;
898         }
899         term->array = $2;
900         $$ = term;
901 }
902 |
903 PE_NAME array '=' PE_VALUE
904 {
905         struct parse_events_term *term;
906
907         if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
908                                         $1, $4, false, &@1, &@4)) {
909                 free($1);
910                 free($2.ranges);
911                 YYABORT;
912         }
913         term->array = $2;
914         $$ = term;
915 }
916 |
917 PE_DRV_CFG_TERM
918 {
919         struct parse_events_term *term;
920         char *config = strdup($1);
921
922         ABORT_ON(!config);
923         if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG,
924                                         config, $1, &@1, NULL)) {
925                 free($1);
926                 free(config);
927                 YYABORT;
928         }
929         $$ = term;
930 }
931
932 array:
933 '[' array_terms ']'
934 {
935         $$ = $2;
936 }
937 |
938 PE_ARRAY_ALL
939 {
940         $$.nr_ranges = 0;
941         $$.ranges = NULL;
942 }
943
944 array_terms:
945 array_terms ',' array_term
946 {
947         struct parse_events_array new_array;
948
949         new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges;
950         new_array.ranges = realloc($1.ranges,
951                                 sizeof(new_array.ranges[0]) *
952                                 new_array.nr_ranges);
953         ABORT_ON(!new_array.ranges);
954         memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges,
955                $3.nr_ranges * sizeof(new_array.ranges[0]));
956         free($3.ranges);
957         $$ = new_array;
958 }
959 |
960 array_term
961
962 array_term:
963 PE_VALUE
964 {
965         struct parse_events_array array;
966
967         array.nr_ranges = 1;
968         array.ranges = malloc(sizeof(array.ranges[0]));
969         ABORT_ON(!array.ranges);
970         array.ranges[0].start = $1;
971         array.ranges[0].length = 1;
972         $$ = array;
973 }
974 |
975 PE_VALUE PE_ARRAY_RANGE PE_VALUE
976 {
977         struct parse_events_array array;
978
979         ABORT_ON($3 < $1);
980         array.nr_ranges = 1;
981         array.ranges = malloc(sizeof(array.ranges[0]));
982         ABORT_ON(!array.ranges);
983         array.ranges[0].start = $1;
984         array.ranges[0].length = $3 - $1 + 1;
985         $$ = array;
986 }
987
988 sep_dc: ':' |
989
990 sep_slash_slash_dc: '/' '/' | ':' |
991
992 %%
993
994 void parse_events_error(YYLTYPE *loc, void *parse_state,
995                         void *scanner __maybe_unused,
996                         char const *msg __maybe_unused)
997 {
998         parse_events_evlist_error(parse_state, loc->last_column, "parser error");
999 }