Commit e3caa5f9 authored by Richard Torenvliet's avatar Richard Torenvliet

Merge branch 'master' of github.com:taddeus/peephole

parents 779efaa1 21ff6f23
......@@ -31,9 +31,9 @@ def optimize_block(block):
while remove_redundancies(block) \
| eliminate_common_subexpressions(block) \
| fold_constants(block) \
| copy_propagation(block)\
| algebraic_transformations(block) \
| copy_propagation(block) \
| eliminate_dead_code(block):
#| algebraic_transformations(block) \
pass
......
......@@ -149,22 +149,44 @@ def fold_constants(block):
register[s[0]] = constants[s[1]]
elif s.name == 'mflo':
# Move of `Lo' register to another register
register[s[0]] = register['Lo']
register[s[0]] = register['$lo']
elif s.name == 'mfhi':
# Move of `Hi' register to another register
register[s[0]] = register['Hi']
register[s[0]] = register['$hi']
elif s.name in ['mult', 'div'] \
and s[0] in register and s[1] in register:
and s[0]in register and s[1] in register:
# Multiplication/division with constants
rs, rt = s
a, b = register[rs], register[rt]
if s.name == 'mult':
binary = bin(register[rs] * register[rt])[2:]
if not a or not b:
# Multiplication by 0
hi = lo = to_hex(0)
elif a == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(b)
elif b == 1:
# Multiplication by 1
hi = to_hex(0)
lo = to_hex(a)
else:
# Calculate result and fill Hi/Lo registers
binary = bin(a * b)[2:]
binary = '0' * (64 - len(binary)) + binary
register['Hi'] = int(binary[:32], base=2)
register['Lo'] = int(binary[32:], base=2)
hi = int(binary[:32], base=2)
lo = int(binary[32:], base=2)
# Replace the multiplication with two immidiate loads to the
# Hi/Lo registers
block.replace(1, [S('command', 'li', '$hi', hi),
S('command', 'li', '$lo', li)])
elif s.name == 'div':
register['Lo'], register['Hi'] = divmod(rs, rt)
lo, hi = divmod(rs, rt)
register['$lo'], register['$hi'] = lo, hi
changed = True
elif s.name in ['addu', 'subu']:
# Addition/subtraction with constants
rd, rs, rt = s
......@@ -187,7 +209,9 @@ def fold_constants(block):
block.replace(1, [S('command', 'li', rd, result)])
register[rd] = result
changed = True
elif rt_known:
continue
if rt_known:
# a = 10 -> b = c + 10
# b = c + a
s[2] = register[rt]
......@@ -198,9 +222,15 @@ def fold_constants(block):
s[1] = rt
s[2] = register[rs]
changed = True
elif len(s) and s[0] in register:
if s[2] == 0:
# Addition/subtraction with 0
block.replace(1, [S('command', 'move', rd, s[1])])
else:
for reg in s.get_def():
if reg in register:
# Known register is overwritten, remove its value
del register[s[0]]
del register[reg]
return changed
......
......@@ -111,8 +111,8 @@ class Statement:
"""Check if the statement is a logical operator."""
return self.is_command() and re.match('^(xor|or|and)i?$', self.name)
def is_double_aritmethic(self):
"""Check if the statement is a aritmethic .d operator."""
def is_double_arithmetic(self):
"""Check if the statement is a arithmetic .d operator."""
return self.is_command() and \
re.match('^(add|sub|div|mul)\.d$', self.name)
......@@ -153,7 +153,7 @@ class Statement:
instr = ['move', 'addu', 'subu', 'li', 'mtc1', 'dmfc1', 'mov.d']
if self.is_load_non_immediate() or self.is_arith() \
or self.is_logical() or self.is_double_aritmethic() \
or self.is_logical() or self.is_double_arithmetic() \
or self.is_move_from_spec() or self.is_double_unary() \
or self.is_set_if_less() or self.is_convert() \
or self.is_truncate() or self.is_load() \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment