From 547564cc8708aa500fe59812a4b2e7075bf1940c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Tue, 24 Nov 2020 00:44:29 +0000 Subject: [PATCH] add insn-histogram.py from bug #532 https://bugs.libre-soc.org/show_bug.cgi?id=532 --- openpower/sv/insn-histogram.py | 95 ++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 openpower/sv/insn-histogram.py diff --git a/openpower/sv/insn-histogram.py b/openpower/sv/insn-histogram.py new file mode 100644 index 000000000..48b1409cf --- /dev/null +++ b/openpower/sv/insn-histogram.py @@ -0,0 +1,95 @@ +#! /bin/env python3 + +# Feed this script the output of: +# powerpc64le-gnu-objdump -d -M raw --no-show-raw-insn ppc-prog + +# It will print the occurrence count of each opcode, +# and under it, indented by one character, +# the occurrence count of each operand. + +# Registers used as operands or as base addresses are counted +# separately; immediates and offsets are grouped per bit length; +# branch target offsets are grouped by range bit length. + +import sys +import re + +insn = re.compile('\s+(?P[0-9a-f]+):\s+(?P[^ \n]+) *(?P.*)[\n]?') + +opkind = re.compile('(?P-?[0-9]+)|(?P[0-9a-f]+)(?: <.*>)?|(?P-?[0-9]+)\((?Pr[0-9]+)\)') + +histogram = {} + +def count(ops, op): + match = opkind.fullmatch(op) + + if match is None: + op = op + elif match['immediate'] is not None: + op = "%i-bit" % int (op).bit_length () + elif match['branch'] is not None: + op = "%i-bit range" % (int (match['branch'], 16) - + int(addr, 16)).bit_length () + elif match['offset'] is not None: + count(ops, match['offset']) + op = match['basereg'] + else: + raise "unrecognized operand kind" + + if op not in ops: + ops[op] = 1 + else: + ops[op] += 1 + +for line in sys.stdin: + match = insn.fullmatch(line) + if match is None: + continue + + addr = match['addr'] + opcode = match['opcode'] + operands = match['operands'] + + if opcode not in histogram: + ops = {} + histogram[opcode] = [1,ops] + else: + histogram[opcode][0] += 1 + ops = histogram[opcode][1] + + if len(operands) > 0: + for operand in operands.split(','): + count(ops, operand) + +hist = list(histogram.items()) +hist.sort(key = (lambda x : x[1][0])) +for x in hist: + print('%6i %s:' % (x[1][0], x[0])) + ops = list(x[1][1].items()) + ops.sort(key = (lambda x : x[1])) + # split out "-bit" from "-bit range" from "regs" + # first "rNs" or "anything-weird" + for x in ops: + if '-bit' in x[0]: + continue + if x[0].startswith('cr'): + continue + print('\t%6i %s' % (x[1], x[0])) + print() + # now Condition Registers + for x in ops: + if '-bit' in x[0]: + continue + if x[0].startswith('cr'): + print('\t%6i %s' % (x[1], x[0])) + print() + # now "N-bit immediates" + for x in ops: + if x[0].endswith('-bit'): + print('\t%6i %s' % (x[1], x[0])) + print() + # finally "bit-range" immediates + for x in ops: + if '-bit range' in x[0]: + print('\t%6i %s' % (x[1], x[0])) + print() -- 2.30.2