| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 1 |  | 
|  | 2 | %option prefix="parse_events_" | 
| Jiri Olsa | 08d2f76 | 2012-05-21 09:12:52 +0200 | [diff] [blame] | 3 | %option stack | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 4 |  | 
|  | 5 | %{ | 
|  | 6 | #include <errno.h> | 
|  | 7 | #include "../perf.h" | 
|  | 8 | #include "parse-events-bison.h" | 
| Jiri Olsa | 8f707d8 | 2012-03-15 20:09:16 +0100 | [diff] [blame] | 9 | #include "parse-events.h" | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 10 |  | 
|  | 11 | static int __value(char *str, int base, int token) | 
|  | 12 | { | 
|  | 13 | long num; | 
|  | 14 |  | 
|  | 15 | errno = 0; | 
|  | 16 | num = strtoul(str, NULL, base); | 
|  | 17 | if (errno) | 
|  | 18 | return PE_ERROR; | 
|  | 19 |  | 
|  | 20 | parse_events_lval.num = num; | 
|  | 21 | return token; | 
|  | 22 | } | 
|  | 23 |  | 
|  | 24 | static int value(int base) | 
|  | 25 | { | 
|  | 26 | return __value(parse_events_text, base, PE_VALUE); | 
|  | 27 | } | 
|  | 28 |  | 
|  | 29 | static int raw(void) | 
|  | 30 | { | 
|  | 31 | return __value(parse_events_text + 1, 16, PE_RAW); | 
|  | 32 | } | 
|  | 33 |  | 
|  | 34 | static int str(int token) | 
|  | 35 | { | 
|  | 36 | parse_events_lval.str = strdup(parse_events_text); | 
|  | 37 | return token; | 
|  | 38 | } | 
|  | 39 |  | 
|  | 40 | static int sym(int type, int config) | 
|  | 41 | { | 
|  | 42 | parse_events_lval.num = (type << 16) + config; | 
|  | 43 | return PE_VALUE_SYM; | 
|  | 44 | } | 
|  | 45 |  | 
| Jiri Olsa | 8f707d8 | 2012-03-15 20:09:16 +0100 | [diff] [blame] | 46 | static int term(int type) | 
|  | 47 | { | 
|  | 48 | parse_events_lval.num = type; | 
|  | 49 | return PE_TERM; | 
|  | 50 | } | 
|  | 51 |  | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 52 | %} | 
|  | 53 |  | 
| Jiri Olsa | 08d2f76 | 2012-05-21 09:12:52 +0200 | [diff] [blame] | 54 | %x mem | 
|  | 55 |  | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 56 | num_dec		[0-9]+ | 
|  | 57 | num_hex		0x[a-fA-F0-9]+ | 
|  | 58 | num_raw_hex	[a-fA-F0-9]+ | 
|  | 59 | name		[a-zA-Z_*?][a-zA-Z0-9_*?]* | 
| Gleb Natapov | e7c72d8 | 2012-04-17 14:13:45 +0300 | [diff] [blame] | 60 | modifier_event	[ukhpGH]{1,8} | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 61 | modifier_bp	[rwx] | 
|  | 62 |  | 
|  | 63 | %% | 
|  | 64 | cpu-cycles|cycles				{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); } | 
|  | 65 | stalled-cycles-frontend|idle-cycles-frontend	{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); } | 
|  | 66 | stalled-cycles-backend|idle-cycles-backend	{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); } | 
|  | 67 | instructions					{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS); } | 
|  | 68 | cache-references				{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES); } | 
|  | 69 | cache-misses					{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES); } | 
|  | 70 | branch-instructions|branches			{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_INSTRUCTIONS); } | 
|  | 71 | branch-misses					{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BRANCH_MISSES); } | 
|  | 72 | bus-cycles					{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_BUS_CYCLES); } | 
| Namhyung Kim | cc96aa7 | 2012-03-29 19:21:57 +0900 | [diff] [blame] | 73 | ref-cycles					{ return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 74 | cpu-clock					{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_CLOCK); } | 
|  | 75 | task-clock					{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_TASK_CLOCK); } | 
|  | 76 | page-faults|faults				{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS); } | 
|  | 77 | minor-faults					{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MIN); } | 
|  | 78 | major-faults					{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_PAGE_FAULTS_MAJ); } | 
|  | 79 | context-switches|cs				{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CONTEXT_SWITCHES); } | 
|  | 80 | cpu-migrations|migrations			{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_CPU_MIGRATIONS); } | 
|  | 81 | alignment-faults				{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_ALIGNMENT_FAULTS); } | 
|  | 82 | emulation-faults				{ return sym(PERF_TYPE_SOFTWARE, PERF_COUNT_SW_EMULATION_FAULTS); } | 
|  | 83 |  | 
|  | 84 | L1-dcache|l1-d|l1d|L1-data		| | 
|  | 85 | L1-icache|l1-i|l1i|L1-instruction	| | 
|  | 86 | LLC|L2					| | 
|  | 87 | dTLB|d-tlb|Data-TLB			| | 
|  | 88 | iTLB|i-tlb|Instruction-TLB		| | 
|  | 89 | branch|branches|bpu|btb|bpc		| | 
|  | 90 | node					{ return str(PE_NAME_CACHE_TYPE); } | 
|  | 91 |  | 
|  | 92 | load|loads|read				| | 
|  | 93 | store|stores|write			| | 
|  | 94 | prefetch|prefetches			| | 
|  | 95 | speculative-read|speculative-load	| | 
|  | 96 | refs|Reference|ops|access		| | 
|  | 97 | misses|miss				{ return str(PE_NAME_CACHE_OP_RESULT); } | 
|  | 98 |  | 
| Jiri Olsa | 8f707d8 | 2012-03-15 20:09:16 +0100 | [diff] [blame] | 99 | /* | 
|  | 100 | * These are event config hardcoded term names to be specified | 
|  | 101 | * within xxx/.../ syntax. So far we dont clash with other names, | 
|  | 102 | * so we can put them here directly. In case the we have a conflict | 
|  | 103 | * in future, this needs to go into '//' condition block. | 
|  | 104 | */ | 
|  | 105 | config			{ return term(PARSE_EVENTS__TERM_TYPE_CONFIG); } | 
|  | 106 | config1			{ return term(PARSE_EVENTS__TERM_TYPE_CONFIG1); } | 
|  | 107 | config2			{ return term(PARSE_EVENTS__TERM_TYPE_CONFIG2); } | 
| Jiri Olsa | 6b5fc39 | 2012-05-21 09:12:53 +0200 | [diff] [blame] | 108 | name			{ return term(PARSE_EVENTS__TERM_TYPE_NAME); } | 
| Jiri Olsa | 8f707d8 | 2012-03-15 20:09:16 +0100 | [diff] [blame] | 109 | period			{ return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } | 
|  | 110 | branch_type		{ return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } | 
|  | 111 |  | 
| Jiri Olsa | 08d2f76 | 2012-05-21 09:12:52 +0200 | [diff] [blame] | 112 | mem:			{ BEGIN(mem); return PE_PREFIX_MEM; } | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 113 | r{num_raw_hex}		{ return raw(); } | 
|  | 114 | {num_dec}		{ return value(10); } | 
|  | 115 | {num_hex}		{ return value(16); } | 
|  | 116 |  | 
|  | 117 | {modifier_event}	{ return str(PE_MODIFIER_EVENT); } | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 118 | {name}			{ return str(PE_NAME); } | 
|  | 119 | "/"			{ return '/'; } | 
|  | 120 | -			{ return '-'; } | 
|  | 121 | ,			{ return ','; } | 
|  | 122 | :			{ return ':'; } | 
|  | 123 | =			{ return '='; } | 
|  | 124 |  | 
| Jiri Olsa | 08d2f76 | 2012-05-21 09:12:52 +0200 | [diff] [blame] | 125 | <mem>{ | 
|  | 126 | {modifier_bp}		{ return str(PE_MODIFIER_BP); } | 
|  | 127 | :			{ return ':'; } | 
|  | 128 | {num_dec}		{ return value(10); } | 
|  | 129 | {num_hex}		{ return value(16); } | 
|  | 130 | /* | 
|  | 131 | * We need to separate 'mem:' scanner part, in order to get specific | 
|  | 132 | * modifier bits parsed out. Otherwise we would need to handle PE_NAME | 
|  | 133 | * and we'd need to parse it manually. During the escape from <mem> | 
|  | 134 | * state we need to put the escaping char back, so we dont miss it. | 
|  | 135 | */ | 
|  | 136 | .			{ unput(*parse_events_text); BEGIN(INITIAL); } | 
|  | 137 | /* | 
|  | 138 | * We destroy the scanner after reaching EOF, | 
|  | 139 | * but anyway just to be sure get back to INIT state. | 
|  | 140 | */ | 
|  | 141 | <<EOF>>			{ BEGIN(INITIAL); } | 
|  | 142 | } | 
|  | 143 |  | 
| Jiri Olsa | 89812fc | 2012-03-15 20:09:15 +0100 | [diff] [blame] | 144 | %% | 
|  | 145 |  | 
|  | 146 | int parse_events_wrap(void) | 
|  | 147 | { | 
|  | 148 | return 1; | 
|  | 149 | } |