|  | 
 | %parse-param {struct list_head *format} | 
 | %parse-param {char *name} | 
 |  | 
 | %{ | 
 |  | 
 | #include <linux/compiler.h> | 
 | #include <linux/list.h> | 
 | #include <linux/bitmap.h> | 
 | #include <string.h> | 
 | #include "pmu.h" | 
 |  | 
 | extern int perf_pmu_lex (void); | 
 |  | 
 | #define ABORT_ON(val) \ | 
 | do { \ | 
 |         if (val) \ | 
 |                 YYABORT; \ | 
 | } while (0) | 
 |  | 
 | %} | 
 |  | 
 | %token PP_CONFIG PP_CONFIG1 PP_CONFIG2 | 
 | %token PP_VALUE PP_ERROR | 
 | %type <num> PP_VALUE | 
 | %type <bits> bit_term | 
 | %type <bits> bits | 
 |  | 
 | %union | 
 | { | 
 | 	unsigned long num; | 
 | 	DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); | 
 | } | 
 |  | 
 | %% | 
 |  | 
 | format: | 
 | format format_term | 
 | | | 
 | format_term | 
 |  | 
 | format_term: | 
 | PP_CONFIG ':' bits | 
 | { | 
 | 	ABORT_ON(perf_pmu__new_format(format, name, | 
 | 				      PERF_PMU_FORMAT_VALUE_CONFIG, | 
 | 				      $3)); | 
 | } | 
 | | | 
 | PP_CONFIG1 ':' bits | 
 | { | 
 | 	ABORT_ON(perf_pmu__new_format(format, name, | 
 | 				      PERF_PMU_FORMAT_VALUE_CONFIG1, | 
 | 				      $3)); | 
 | } | 
 | | | 
 | PP_CONFIG2 ':' bits | 
 | { | 
 | 	ABORT_ON(perf_pmu__new_format(format, name, | 
 | 				      PERF_PMU_FORMAT_VALUE_CONFIG2, | 
 | 				      $3)); | 
 | } | 
 |  | 
 | bits: | 
 | bits ',' bit_term | 
 | { | 
 | 	bitmap_or($$, $1, $3, 64); | 
 | } | 
 | | | 
 | bit_term | 
 | { | 
 | 	memcpy($$, $1, sizeof($1)); | 
 | } | 
 |  | 
 | bit_term: | 
 | PP_VALUE '-' PP_VALUE | 
 | { | 
 | 	perf_pmu__set_format($$, $1, $3); | 
 | } | 
 | | | 
 | PP_VALUE | 
 | { | 
 | 	perf_pmu__set_format($$, $1, 0); | 
 | } | 
 |  | 
 | %% | 
 |  | 
 | void perf_pmu_error(struct list_head *list __maybe_unused, | 
 | 		    char *name __maybe_unused, | 
 | 		    char const *msg __maybe_unused) | 
 | { | 
 | } |