sdk-core
v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Toggle main menu visibility
Loading...
Searching...
No Matches
shortloop_scan.py
1
#!/usr/bin/env python3
2
"""Usage: shortloop_scan.py <objdump> <elf or .a>...
3
4
Lists R5900 short-loop erratum hazards in EE code: a conditional branch back over 6 or fewer instructions
5
(branch and delay slot included), no other branch or jump inside, and a delay slot that is not a nop."""
6
7
import
re
8
import
subprocess
9
import
sys
10
11
OBJDUMP = sys.argv[1]
12
BRANCHES = {
"beq"
,
"bne"
,
"blez"
,
"bgtz"
,
"bltz"
,
"bgez"
,
"beqz"
,
"bnez"
,
"bc1t"
,
"bc1f"
,
"beql"
,
"bnel"
,
"blezl"
,
13
"bgtzl"
,
"bltzl"
,
"bgezl"
,
"bc1tl"
,
"bc1fl"
,
"bltzal"
,
"bgezal"
,
"bc0t"
,
"bc0f"
}
14
JUMPS = {
"j"
,
"jal"
,
"jr"
,
"jalr"
,
"b"
,
"bal"
,
"eret"
,
"syscall"
,
"break"
}
15
16
for
elf
in
sys.argv[2:]:
17
out = subprocess.run([OBJDUMP,
"-d"
, elf], capture_output=
True
, text=
True
).stdout
18
sections, ins, func, member = [], [],
"?"
, elf
19
for
line
in
out.splitlines():
20
if
"file format"
in
line
or
line.startswith(
"Disassembly of section"
):
21
if
ins:
22
sections.append((member, ins))
23
ins = []
24
if
"file format"
in
line:
25
member = line.split(
":"
)[0]
26
continue
27
m = re.match(
r"^([0-9a-f]+) <(.+)>:$"
, line)
28
if
m:
29
func = m.group(2)
30
continue
31
m = re.match(
r"^\s*([0-9a-f]+):\t[0-9a-f]+ \t(\S+)\s*(.*)$"
, line)
32
if
m:
33
ins.append((int(m.group(1), 16), m.group(2), m.group(3), func))
34
if
ins:
35
sections.append((member, ins))
36
hazards = 0
37
for
member, ins
in
sections:
38
index = {a: i
for
i, (a, _, _, _)
in
enumerate(ins)}
39
for
i, (addr, op, args, func)
in
enumerate(ins):
40
if
op
not
in
BRANCHES:
41
continue
42
t = re.search(
r"([0-9a-f]+) <"
, args)
43
if
not
t:
44
continue
45
target = int(t.group(1), 16)
46
if
target > addr
or
target
not
in
index:
47
continue
48
n = (addr - target) // 4 + 2
49
if
n > 6
or
i + 1 >= len(ins):
50
continue
51
body = ins[index[target]:i]
52
if
any(o
in
BRANCHES
or
o
in
JUMPS
for
_, o, _, _
in
body):
53
continue
54
slot = ins[i + 1]
55
if
slot[1] ==
"nop"
or
op.endswith(
"l"
):
56
continue
57
hazards += 1
58
print(f
"{member}: {func} {addr:08x} {op} {args} | {n} instructions, slot: {slot[1]} {slot[2]}"
)
59
print(f
"{elf}: {hazards} hazards"
)
tests
bench
shortloop_scan.py
Generated by
1.18.0