Эх сурвалжийг харах

Added optimization of bne.

Jayke Meijer 14 жил өмнө
parent
commit
1af3567df0
4 өөрчлөгдсөн 55 нэмэгдсэн , 11 устгасан
  1. 16 1
      src/optimize.py
  2. 1 1
      src/parser.py
  3. 8 6
      src/writer.py
  4. 30 3
      tests/test_optimize.py

+ 16 - 1
src/optimize.py

@@ -81,6 +81,20 @@ def optimize_global(statements):
                         s.name = 'bne'
                         s[2] = j[0]
                         statements.replace(3, [s, label])
+                        
+            #     bne ..., $Lx          ->      beq ..., $Ly
+            #     j $Ly                     $Lx:
+            # $Lx:
+            if s.is_command('bne'):
+                following = statements.peek(2)
+
+                if len(following) == 2:
+                    j, label = following
+
+                    if j.is_command('j') and label.is_label(s[2]):
+                        s.name = 'beq'
+                        s[2] = j[0]
+                        statements.replace(3, [s, label])
 
 
 def optimize_blocks(blocks):
@@ -127,7 +141,8 @@ def optimize(statements, verbose=0):
 
     # Optimize basic blocks
     basic_blocks = find_basic_blocks(statements)
-    blocks = optimize_blocks(basic_blocks)
+#    blocks = optimize_blocks(basic_blocks)
+    blocks = basic_blocks
     block_statements = map(lambda b: b.statements, blocks)
     opt_blocks = reduce(lambda a, b: a + b, block_statements)
     b = len(opt_blocks)

+ 1 - 1
src/parser.py

@@ -32,7 +32,7 @@ def t_DIRECTIVE(t):
     return t
 
 def t_hex_word(t):
-    r'0x[0-9a-fA-F]{8}'
+    r'0x([0-9a-fA-F]{8}|[0-9a-fA-F]{4})'
     t.type = 'WORD'
     return t
 

+ 8 - 6
src/writer.py

@@ -12,13 +12,15 @@ def write_statements(statements):
         if s.is_label():
             line = s.name + ':'
             indent_level = 1
-        elif s.is_inline_comment():
-            line = '#' + s.name
-            l = len(prevline.expandtabs(4))
-            tabs = int(ceil((24 - l) / 4.)) + 1
-            newline = '\t' * tabs
         elif s.is_comment():
-            line = '\t' * indent_level + line
+            line = '#' + s.name
+            
+            if s.is_inline_comment():
+                l = len(prevline.expandtabs(4))
+                tabs = int(ceil((24 - l) / 4.)) + 1
+                newline = '\t' * tabs
+            else:
+                line = '\t' * indent_level + line
         elif s.is_directive():
             line = '\t' + s.name
         elif s.is_command():

+ 30 - 3
tests/test_optimize.py

@@ -184,9 +184,6 @@ class TestOptimize(unittest.TestCase):
         self.assertEquals(block2.statements, arguments2)
         self.assertEquals(block3.statements, arguments3)
         
-    #     beq ..., $Lx          ->      bne ..., $Ly
-    #     j $Ly                     $Lx:
-    # $Lx:
     def test_optimize_global_beq_j_true(self):
         foo = S('command', 'foo')
         bar = S('command', 'bar')
@@ -216,3 +213,33 @@ class TestOptimize(unittest.TestCase):
         optimize_global(block)
         
         self.assertEquals(block.statements, arguments)
+        
+    def test_optimize_global_bne_j_true(self):
+        foo = S('command', 'foo')
+        bar = S('command', 'bar')
+        
+        block = B([foo,
+                   S('command', 'bne', '$regA', '$regB', '$Lx'),
+                   S('command', 'j', '$Ly'),
+                   S('label', '$Lx'),
+                   bar])
+        optimize_global(block)
+        
+        self.assertEquals(block.statements, [foo,
+                   S('command', 'beq', '$regA', '$regB', '$Ly'),
+                   S('label', '$Lx'),
+                   bar])
+                   
+    def test_optimize_global_bne_j_false(self):
+        foo = S('command', 'foo')
+        bar = S('command', 'bar')
+        
+        arguments = [foo, \
+                     S('command', 'bne', '$regA', '$regB', '$Lz'), \
+                     S('command', 'j', '$Ly'), \
+                     S('label', '$Lx'), \
+                     bar]
+        block = B(arguments)
+        optimize_global(block)
+        
+        self.assertEquals(block.statements, arguments)