aboutsummaryrefslogtreecommitdiff
path: root/devtools
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2011-06-16 15:33:26 +0200
committerWillem Jan Palenstijn2011-06-16 15:40:52 +0200
commit287c23f1263c77fa04d2a697f441d362ed419b5d (patch)
tree9ca27e1e995f1a96c2e33a82cedc3003ebf8ff97 /devtools
parentd8d16e0231272e73f72630c5a1966db6f1e29809 (diff)
downloadscummvm-rg350-287c23f1263c77fa04d2a697f441d362ed419b5d.tar.gz
scummvm-rg350-287c23f1263c77fa04d2a697f441d362ed419b5d.tar.bz2
scummvm-rg350-287c23f1263c77fa04d2a697f441d362ed419b5d.zip
DREAMWEB: Try to clean up jumps to returns
Diffstat (limited to 'devtools')
-rw-r--r--devtools/tasmrecover/tasm/cpp.py4
-rw-r--r--devtools/tasmrecover/tasm/proc.py40
2 files changed, 35 insertions, 9 deletions
diff --git a/devtools/tasmrecover/tasm/cpp.py b/devtools/tasmrecover/tasm/cpp.py
index 3e5ae78438..5d460961a6 100644
--- a/devtools/tasmrecover/tasm/cpp.py
+++ b/devtools/tasmrecover/tasm/cpp.py
@@ -241,6 +241,9 @@ namespace %s {
self.add_forward(name)
return "{ %s(context); return; }" %name
else:
+ # TODO: name or self.resolve_label(name) or self.mangle_label(name)??
+ if name in self.proc.retlabels:
+ return "return /* (%s) */" % (name,)
return "goto %s" %self.resolve_label(name)
def _label(self, name):
@@ -443,6 +446,7 @@ namespace %s {
self.proc = proc_module.proc(name)
self.proc.stmts = copy(src_proc.stmts)
self.proc.labels = copy(src_proc.labels)
+ self.proc.retlabels = copy(src_proc.retlabels)
#for p in xrange(skip, len(self.proc.stmts)):
# s = self.proc.stmts[p]
# if isinstance(s, op.basejmp):
diff --git a/devtools/tasmrecover/tasm/proc.py b/devtools/tasmrecover/tasm/proc.py
index 1350ea1e0b..e5af1afae5 100644
--- a/devtools/tasmrecover/tasm/proc.py
+++ b/devtools/tasmrecover/tasm/proc.py
@@ -9,6 +9,7 @@ class proc:
self.calls = []
self.stmts = []
self.labels = set()
+ self.retlabels = set()
self.__label_re = re.compile(r'^(\S+):(.*)$')
self.offset = proc.last_addr
proc.last_addr += 4
@@ -67,13 +68,20 @@ class proc:
def optimize(self):
print "optimizing..."
- #trivial simplifications, removing last ret
+ #trivial simplifications
while len(self.stmts) and isinstance(self.stmts[-1], op.label):
print "stripping last label"
self.stmts.pop()
- if isinstance(self.stmts[-1], op._ret) and (len(self.stmts) < 2 or not isinstance(self.stmts[-2], op.label)):
- print "stripping last ret"
- self.stmts.pop()
+ #mark labels that directly precede a ret
+ for i in range(len(self.stmts)):
+ if not isinstance(self.stmts[i], op.label):
+ continue
+ j = i
+ while j < len(self.stmts) and isinstance(self.stmts[j], op.label):
+ j += 1
+ if j == len(self.stmts) or isinstance(self.stmts[j], op._ret):
+ print "Return label: %s" % (self.stmts[i].name,)
+ self.retlabels.add(self.stmts[i].name)
#merging push ax pop bx constructs
i = 0
while i + 1 < len(self.stmts):
@@ -102,15 +110,29 @@ class proc:
continue
print "checking label %s..." %s.name
used = False
- for j in self.stmts:
- if isinstance(j, op.basejmp) and j.label == s.name:
- print "used"
- used = True
- break
+ if s.name not in self.retlabels:
+ for j in self.stmts:
+ if isinstance(j, op.basejmp) and j.label == s.name:
+ print "used"
+ used = True
+ break
if not used:
print self.labels
self.remove_label(s.name)
+ #removing duplicate rets
+ i = 0
+ while i < len(self.stmts)-1:
+ if isinstance(self.stmts[i], op._ret) and isinstance(self.stmts[i+1], op._ret):
+ del self.stmts[i]
+ else:
+ i += 1
+
+ #removing last ret
+ while len(self.stmts) > 0 and isinstance(self.stmts[-1], op._ret) and (len(self.stmts) < 2 or not isinstance(self.stmts[-2], op.label)):
+ print "stripping last ret"
+ self.stmts.pop()
+
self.optimize_sequence(op._stosb);
self.optimize_sequence(op._stosw);
self.optimize_sequence(op._movsb);