1 2 %option prefix="parse_events_" 3 %option stack 4 5 %{ 6 #include <errno.h> 7 #include "../perf.h" 8 #include "parse-events-bison.h" 9 #include "parse-events.h" 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 46 static int term(int type) 47 { 48 parse_events_lval.num = type; 49 return PE_TERM; 50 } 51 52 %} 53 54 %x mem 55 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_*?]* 60 modifier_event [ukhpGH]{1,8} 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); } 73 ref-cycles { return sym(PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES); } 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 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); } 108 name { return term(PARSE_EVENTS__TERM_TYPE_NAME); } 109 period { return term(PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); } 110 branch_type { return term(PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); } 111 112 mem: { BEGIN(mem); return PE_PREFIX_MEM; } 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); } 118 {name} { return str(PE_NAME); } 119 "/" { return '/'; } 120 - { return '-'; } 121 , { return ','; } 122 : { return ':'; } 123 = { return '='; } 124 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 144 %% 145 146 int parse_events_wrap(void) 147 { 148 return 1; 149 } 150