bc2164472d375772728c1c8e10d151dc31d58c90
2 # see https://bugs.libre-soc.org/show_bug.cgi?id=532
4 # Print a per-opcode histogram for ppc asm.
7 # This script is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # This script is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this script; see the file COPYING3. If not see
19 # <http://www.gnu.org/licenses/>.
21 # Originally by Alexandre Oliva <oliva@gnu.org>.
24 # Feed this script the output of:
25 # powerpc64le-gnu-objdump -d -M raw --no-show-raw-insn ppc-prog
27 # It will print the occurrence count of each opcode,
28 # and under it, indented by one character,
29 # the occurrence count of each operand.
31 # Registers used as operands or as base addresses are counted
32 # separately; immediates and offsets are grouped per bit length;
33 # branch target offsets are grouped by range bit length.
38 insn
= re
.compile('\s+(?P<addr>[0-9a-f]+):\s+(?P<opcode>[^ \n]+) *(?P<operands>.*)[\n]?')
40 opkind
= re
.compile('(?P<immediate>-?[0-9]+)|(?P<branch>[0-9a-f]+)(?: <.*>)?|(?P<offset>-?[0-9]+)\((?P<basereg>r[0-9]+)\)')
45 match
= opkind
.fullmatch(op
)
49 elif match
['immediate'] is not None:
50 op
= "%i-bit" % int (op
).bit_length ()
51 elif match
['branch'] is not None:
52 op
= "%i-bit range" % (int (match
['branch'], 16) -
53 int(addr
, 16)).bit_length ()
54 elif match
['offset'] is not None:
55 count(ops
, match
['offset'])
58 raise "unrecognized operand kind"
65 for line
in sys
.stdin
:
66 match
= insn
.fullmatch(line
)
71 opcode
= match
['opcode']
72 operands
= match
['operands']
74 if opcode
not in histogram
:
76 histogram
[opcode
] = [1,ops
]
78 histogram
[opcode
][0] += 1
79 ops
= histogram
[opcode
][1]
82 for operand
in operands
.split(','):
88 # for each instruction print out a regcount. first, sort by instr count
89 hist
= list(histogram
.items())
90 hist
.sort(key
= (lambda x
: x
[1][0]))
92 # now print each instruction and its register usage
94 print('%6i %s:' % (x
[1][0], x
[0]))
95 ops
= list(x
[1][1].items())
96 ops
.sort(key
= (lambda x
: x
[1]))
98 # split out "-bit" from "-bit range" from "regs"
100 # first "rNs" or "anything-weird"
104 if x
[0].startswith('cr'):
106 print('\t%6i %s' % (x
[1], x
[0]))
107 # total up integer register counts
108 if not x
[0].startswith('r'):
110 if not x
[0] in intregcounts
:
111 intregcounts
[x
[0]] = 0
112 intregcounts
[x
[0]] += x
[1]
117 # now Condition Registers
121 if x
[0].startswith('cr'):
122 print('\t%6i %s' % (x
[1], x
[0]))
123 if not x
[0] in crregcounts
:
124 crregcounts
[x
[0]] = 0
125 crregcounts
[x
[0]] += x
[1]
128 # now "N-bit immediates"
130 if x
[0].endswith('-bit'):
131 print('\t%6i %s' % (x
[1], x
[0]))
134 # finally "bit-range" immediates
136 if '-bit range' in x
[0]:
137 print('\t%6i %s' % (x
[1], x
[0]))
140 # print out regs usage totals (TODO: FP)
141 for regcounts
in [intregcounts
, crregcounts
]:
142 regnums
= list(regcounts
.items())
143 regnums
.sort(key
= (lambda x
: x
[1]))
145 print('%6i %s' % (x
[1], x
[0]))