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) | 
