aboutsummaryrefslogtreecommitdiff
path: root/parser.py
blob: 8d3cc0411c1f24400c44d3c1b42ec555fb31ca46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#!/usr/bin/env python

import sys
import argparse

counter_labels = {
  'a53' : {
    'r00': 'Software increment. The register is incremented only on writes to the Software Increment Register.',
    'r01': 'L1 Instruction cache refill.',
    'r02': 'L1 Instruction TLB refill.',
    'r03': 'L1 Data cache refill.',
    'r04': 'L1 Data cache access.',
    'r05': 'L1 Data TLB refill.',
    'r06': 'Instruction architecturally executed, condition check pass - load.',
    'r07': 'Instruction architecturally executed, condition check pass - store.',
    'r08': 'Instruction architecturally executed.',
    'r09': 'Exception taken.',
    'r0A': 'Exception return.',
    'r0B': 'Change to Context ID retired.',
    'r0C': 'Instruction architecturally executed, condition check pass, software change of the PC.',
    'r0D': 'Instruction architecturally executed, immediate branch.',
    'r0E': 'Instruction architecturally executed, condition code check pass, procedure return.',
    'r0F': 'Instruction architecturally executed, condition check pass, unaligned load or store.',
    'r10': 'Mispredicted or not predicted branch speculatively executed.',
    'r11': 'Cycle.',
    'r12': 'Predictable branch speculatively executed.',
    'r13': 'Data memory access.',
    'r14': 'L1 Instruction cache access.',
    'r15': 'L1 Data cache Write-Back.',
    'r16': 'L2 Data cache access.',
    'r17': 'L2 Data cache refill.',
    'r18': 'L2 Data cache Write-Back.',
    'r19': 'Bus access.',
    'r1A': 'Local memory error.',
    'r1D': 'Bus cycle.',
    'r1E': 'Odd performance counter chain mode.',
    'r60': 'Bus access - Read.',
    'r61': 'Bus access - Write.',
    'r7A': 'Branch speculatively executed - Indirect branch.',
    'r86': 'Exception taken, IRQ.',
    'r87': 'Exception taken, FIQ.',
    'rC0': 'External memory request.',
    'rC1': 'Non-cacheable external memory request.',
    'rC2': 'Linefill because of prefetch.',
    'rC3': 'Instruction Cache Throttle occurred.',
    'rC4': 'Entering read allocate mode.',
    'rC5': 'Read allocate mode.',
    'rC6': 'Pre-decode error.',
    'rC7': 'Data Write operation that stalls the pipeline because the store buffer is full.',
    'rC8': 'SCU Snooped data from another CPU for this CPU.',
    'rC9': 'Conditional branch executed.',
    'rCA': 'Indirect branch mispredicted.',
    'rCB': 'Indirect branch mispredicted because of address miscompare.',
    'rCC': 'Conditional branch mispredicted.',
    'rD0': 'L1 Instruction Cache (data or tag) memory error.',
    'rD1': 'L1 Data Cache (data, tag or dirty) memory error, correctable or non-correctable.',
    'rD2': 'TLB memory error.',
    'rE0': 'Attributable Performance Impact Event. Counts every cycle that the DPU IQ is empty and that is not because of a recent micro-TLB miss, instruction cache miss or pre-decode error.',
    'rE1': 'Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is an instruction cache miss being processed.',
    'rE2': 'Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is an instruction micro-TLB miss being processed.',
    'rE3': 'Attributable Performance Impact Event. Counts every cycle the DPU IQ is empty and there is a pre-decode error being processed.',
    'rE4': 'Attributable Performance Impact Event. Counts every cycle there is an interlock that is not because of an Advanced SIMD or Floating-point instruction, and not because of a load/store instruction waiting for data to calculate the address in the AGU.  Stall cycles because of a stall in Wr, typically awaiting load data, are excluded.',
    'rE5': 'Attributable Performance Impact Event. Counts every cycle there is an interlock that is because of a load/store instruction waiting for data to calculate the address in the AGU.  Stall cycles because of a stall in Wr, typically awaiting load data, are excluded.',
    'rE6': 'Attributable Performance Impact Event. Counts every cycle there is an interlock that is because of an Advanced SIMD or Floating-point instruction.  Stall cycles because of a stall in the Wr stage, typically awaiting load data, are excluded.',
    'rE7': 'Attributable Performance Impact Event. Counts every cycle there is a stall in the Wr stage because of a load miss.',
    'rE8': 'Attributable Performance Impact Event. Counts every cycle there is a stall in the Wr stage because of a store.',
  },
  'a57' : {
    'r00': 'Instruction architecturally executed (condition check pass) - Software increment',
    'r01': 'Level 1 instruction cache refill',
    'r02': 'Level 1 instruction TLB refill',
    'r03': 'Level 1 data cache refill',
    'r04': 'Level 1 data cache access',
    'r05': 'Level 1 data TLB refill',
    'r08': 'Instruction architecturally executed',
    'r09': 'Exception taken',
    'r0A': 'Instruction architecturally executed (condition check pass) - Exception return',
    'r0B': 'Instruction architecturally executed (condition check pass) - Write to CONTEXTIDR',
    'r10': 'Mispredicted or not predicted branch speculatively executed',
    'r11': 'Cycle',
    'r12': 'Predictable branch speculatively executed',
    'r13': 'Data memory access',
    'r14': 'Level 1 instruction cache access',
    'r15': 'Level 1 data cache Write-Back',
    'r16': 'Level 2 data cache access',
    'r17': 'Level 2 data cache refill',
    'r18': 'Level 2 data cache Write-Back',
    'r19': 'Bus access',
    'r1A': 'Local memory error',
    'r1B': 'Operation speculatively executed',
    'r1C': 'Instruction architecturally executed (condition check pass) - Write to translation table base',
    'r1D': 'Bus cycle',
    'r1E': 'Odd performance counter chain mode',
    'r40': 'Level 1 data cache access - Read',
    'r41': 'Level 1 data cache access - Write',
    'r42': 'Level 1 data cache refill - Read',
    'r43': 'Level 1 data cache refill - Write',
    'r46': 'Level 1 data cache Write-back - Victim',
    'r47': 'Level 1 data cache Write-back - Cleaning and coherency',
    'r48': 'Level 1 data cache invalidate',
    'r4C': 'Level 1 data TLB refill - Read',
    'r4D': 'Level 1 data TLB refill - Write',
    'r50': 'Level 2 data cache access - Read',
    'r51': 'Level 2 data cache access - Write',
    'r52': 'Level 2 data cache refill - Read',
    'r53': 'Level 2 data cache refill - Write',
    'r56': 'Level 2 data cache Write-back - Victim',
    'r57': 'Level 2 data cache Write-back - Cleaning and coherency',
    'r58': 'Level 2 data cache invalidate',
    'r60': 'Bus access - Read',
    'r61': 'Bus access - Write',
    'r62': 'Bus access - Normal',
    'r63': 'Bus access - Not normal',
    'r64': 'Bus access - Normal',
    'r65': 'Bus access - Peripheral',
    'r66': 'Data memory access - Read',
    'r67': 'Data memory access - Write',
    'r68': 'Unaligned access - Read',
    'r69': 'Unaligned access - Write',
    'r6A': 'Unaligned access',
    'r6C': 'Exclusive operation speculatively executed - LDREX',
    'r6D': 'Exclusive instruction speculatively executed - STREX pass',
    'r6E': 'Exclusive operation speculatively executed - STREX fail',
    'r70': 'Operation speculatively executed - Load',
    'r71': 'Operation speculatively executed - Store',
    'r72': 'Operation speculatively executed - Load or store',
    'r73': 'Operation speculatively executed - Integer data processing',
    'r74': 'Operation speculatively executed - Advanced SIMD',
    'r75': 'Operation speculatively executed - VFP',
    'r76': 'Operation speculatively executed - Software change of the PC',
    'r77': 'Operation speculatively executed, crypto data processing',
    'r78': 'Branch speculatively executed - Immediate branch',
    'r79': 'Branch speculatively executed - Procedure return',
    'r7A': 'Branch speculatively executed - Indirect branch',
    'r7C': 'Barrier speculatively executed - ISB',
    'r7D': 'Barrier speculatively executed - DSB',
    'r7E': 'Barrier speculatively executed - DMB',
    'r81': 'Exception taken, other synchronous',
    'r82': 'Exception taken, Supervisor Call',
    'r83': 'Exception taken, Instruction Abort',
    'r84': 'Exception taken, Data Abort or SError',
    'r86': 'Exception taken, IRQ',
    'r87': 'Exception taken, FIQ',
    'r88': 'Exception taken, Secure Monitor Call',
    'r8A': 'Exception taken, Hypervisor Call',
    'r8B': 'Exception taken, Instruction Abort not taken locally',
    'r8C': 'Exception taken, Data Abort, or SError not taken locally',
    'r8D': 'Exception taken - Other traps not taken locally',
    'r8E': 'Exception taken, IRQ not taken locally',
    'r8F': 'Exception taken, FIQ not taken locally',
    'r90': 'Release consistency instruction speculatively executed - Load-Acquire',
    'r91': 'Release consistency instruction speculatively executed - Store-Release',
  },
}

def ordered_set(items):
  seen = set()
  return [ x for x in items if not (x in seen or seen.add(x)) ]

#Parser
class CounterLabelsAction(argparse.Action):
  def __init__(self, option_strings, dest, nargs=None, **kwargs):
    if nargs is not None:
      raise ValueError("nargs not allowed")
    super(CounterLabelsAction, self).__init__(option_strings, dest, **kwargs)
  def __call__(self, parser, namespace, values, option_string):
    global counter_labels
    counter_labels = counter_labels[values]
parser = argparse.ArgumentParser()
parser.add_argument('--core', '-c', choices=counter_labels.keys(), action=CounterLabelsAction)
parser.add_argument('input', type=argparse.FileType('r'))
args = parser.parse_args()

#Globals
binary_list=[]
binary_args_list=[]
counter_list=[]
results={}

lines=args.input.read().splitlines()
for line in lines:
  if line.startswith(': '):
    words = line.split()
    binary = words[1]
    binary_args = ' '.join(words[2:-1])
    if not binary in results:
      results[binary] = {}
    if not binary_args in results[binary]:
        results[binary][binary_args] = {}

    #For ordering
    binary_list.append(binary)
    binary_args_list.append(binary_args)
  elif not line[0].isdigit():
    (counter, count) = line.split()
    if counter in counter_labels:
      counter = counter_labels[counter]
    counter_list.append(counter) #For ordering
    if counter in results[binary][binary_args]:
      results[binary][binary_args][counter].append(count)
    else:
      results[binary][binary_args][counter] = [count]

binary_set = ordered_set(binary_list)
binary_args_set = ordered_set(binary_args_list)
counter_set = ordered_set(counter_list)

table = []
for binary in binary_set:
  for binary_args in binary_args_set:
    while len(results[binary][binary_args][counter_set[0]]) != 0:
      row = [binary, binary_args]
      for counter in counter_set:
        try:
          row.append(results[binary][binary_args][counter].pop(0))
        except IndexError:
          print "\n*** UNBALANCED COUNTER RESULTS - is the input file complete?"
          sys.exit(1)
      table.append(row)

headers=['Binary', 'Args']
headers.extend(counter_set)
print '\t'.join(headers)
for row in table:
  print '\t'.join(row)