diff options
author | Vladimir | 2011-06-05 15:05:12 +0400 |
---|---|---|
committer | Alyssa Milburn | 2011-06-15 17:29:44 +0200 |
commit | 9cf2a7ba0e686b35a4f1041f67c51cb9ef2fa867 (patch) | |
tree | 6d7d41f4443878cb323717b2ef0a0ee246f1e40e /devtools/tasmrecover/tasm/proc.py | |
parent | 1f063c947b34ba9e56fabcbdf838094da80b3727 (diff) | |
download | scummvm-rg350-9cf2a7ba0e686b35a4f1041f67c51cb9ef2fa867.tar.gz scummvm-rg350-9cf2a7ba0e686b35a4f1041f67c51cb9ef2fa867.tar.bz2 scummvm-rg350-9cf2a7ba0e686b35a4f1041f67c51cb9ef2fa867.zip |
DREAMWEB: added tasm-recover tool
Diffstat (limited to 'devtools/tasmrecover/tasm/proc.py')
-rw-r--r-- | devtools/tasmrecover/tasm/proc.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/devtools/tasmrecover/tasm/proc.py b/devtools/tasmrecover/tasm/proc.py new file mode 100644 index 0000000000..4337d4c936 --- /dev/null +++ b/devtools/tasmrecover/tasm/proc.py @@ -0,0 +1,84 @@ +import re +import op + +class proc: + last_addr = 0xc000 + + def __init__(self, name): + self.name = name + self.calls = [] + self.stmts = [] + self.labels = set() + self.__label_re = re.compile(r'^(\S+):(.*)$') + self.offset = proc.last_addr + proc.last_addr += 4 + + def add_label(self, label): + self.stmts.append(op.label(label)) + self.labels.add(label) + + def optimize(self): + print "optimizing..." + #trivial simplifications, removing last ret + 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() + #merging push ax pop bx constructs + i = 0 + while i + 1 < len(self.stmts): + a, b = self.stmts[i], self.stmts[i + 1] + if isinstance(a, op._push) and isinstance(b, op._pop): + ar, br = a.regs, b.regs + movs = [] + while len(ar) and len(br): + src = ar.pop() + dst = br.pop(0) + movs.append(op._mov2(dst, src)) + if len(br) == 0: + self.stmts.pop(i + 1) + print "merging %d push-pops into movs" %(len(movs)) + for m in movs: + print "\t%s <- %s" %(m.dst, m.src) + self.stmts[i + 1:i + 1] = movs + if len(ar) == 0: + self.stmts.pop(i) + else: + i += 1 + #fixme: add local? + + def add(self, stmt): + #print stmt + comment = stmt.rfind(';') + if comment >= 0: + stmt = stmt[:comment] + stmt = stmt.strip() + + r = self.__label_re.search(stmt) + if r is not None: + #label + self.add_label(r.group(1).lower()) + #print "remains: %s" %r.group(2) + stmt = r.group(2).strip() + + if len(stmt) == 0: + return + + s = stmt.split(None) + cmd = s[0] + cl = getattr(op, '_' + cmd) + arg = " ".join(s[1:]) if len(s) > 1 else str() + o = cl(arg) + self.stmts.append(o) + + def __str__(self): + r = [] + for i in self.stmts: + r.append(i.__str__()) + return "\n".join(r) + + def visit(self, visitor, skip = 0): + for i in xrange(skip, len(self.stmts)): + self.stmts[i].visit(visitor) |