Add lxo/ChangeLog, and throw-away-me-not :-) scripts written for PR532
[libreriscv.git] / lxo / 532 / insn-histogram.py
1 #! /bin/env python3
2
3 # Feed this script the output of objdump -M raw --no-show-raw-insn ppc-prog
4
5 # It will print the occurrence count of each opcode,
6 # and under it, indented by one character,
7 # the occurrence count of each operand.
8
9 # Registers used as operands or as base addresses are counted
10 # separately; immediates and offsets are grouped per bit length;
11 # branch target offsets are grouped by range bit length.
12
13 import sys
14 import re
15
16 insn = re.compile('\s+(?P<addr>[0-9a-f]+):\s+(?P<opcode>[^ \n]+) *(?P<operands>.*)[\n]?')
17
18 opkind = re.compile('(?P<immediate>-?[0-9]+)|(?P<branch>[0-9a-f]+)(?: <.*>)?|(?P<offset>-?[0-9]+)\((?P<basereg>r[0-9]+)\)')
19
20 histogram = {}
21
22 def count(ops, op):
23 match = opkind.fullmatch(op)
24
25 if match is None:
26 op = op
27 elif match['immediate'] is not None:
28 op = "%i-bit" % int (op).bit_length ()
29 elif match['branch'] is not None:
30 op = "%i-bit range" % (int (match['branch'], 16) - int (addr, 16)).bit_length ()
31 elif match['offset'] is not None:
32 count(ops, match['offset'])
33 op = match['basereg']
34 else:
35 raise "unrecognized operand kind"
36
37 if op not in ops:
38 ops[op] = 1
39 else:
40 ops[op] += 1
41
42 for line in sys.stdin:
43 match = insn.fullmatch(line)
44 if match is None:
45 continue
46
47 addr = match['addr']
48 opcode = match['opcode']
49 operands = match['operands']
50
51 if opcode not in histogram:
52 ops = {}
53 histogram[opcode] = [1,ops]
54 else:
55 histogram[opcode][0] += 1
56 ops = histogram[opcode][1]
57
58 if len(operands) > 0:
59 for operand in operands.split(','):
60 count(ops, operand)
61
62 hist = list(histogram.items())
63 hist.sort(key = (lambda x : x[1][0]))
64 for x in hist:
65 print('%6i %s:' % (x[1][0], x[0]))
66 ops = list(x[1][1].items())
67 ops.sort(key = (lambda x : x[1]))
68 for x in ops:
69 print(' %6i %s' % (x[1], x[0]))