Skip to content

Commit bd894f1

Browse files
committed
Bugfix: call partition in basic blocks
Calls must be partitioned like jp/jr. The "next" block is not the one upon return. Also adds some testing for basic blocks
1 parent 444e213 commit bd894f1

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

arch/zx48k/optimizer/basicblock.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ def update_goes_and_comes(self):
332332
self.add_goes_to(self.next)
333333

334334
elif inst == 'call':
335+
if cond is None:
336+
self.delete_goes(self.next)
337+
self.next = LABELS[oper[0]].basic_block
338+
335339
LABELS[oper[0]].basic_block.add_comes_from(self)
336340
stack = [LABELS[oper[0]].basic_block]
337341
bbset = IdentitySet()
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import unittest
4+
from arch.zx48k.optimizer import basicblock
5+
6+
7+
class TestBasicBlock(unittest.TestCase):
8+
""" Tests basic blocks implementation
9+
"""
10+
def setUp(self):
11+
self.blk = basicblock.BasicBlock([])
12+
13+
def test_block_partition_jp(self):
14+
code = """
15+
nop
16+
jp __UNKNOWN
17+
nop
18+
"""
19+
self.blk.code = [x for x in code.split('\n') if x.strip()]
20+
blks = basicblock.get_basic_blocks(self.blk)
21+
self.assertEqual(len(blks), 2)
22+
self.assertEqual(blks[0].code, ['nop', 'jp __UNKNOWN'])
23+
self.assertEqual(blks[1].code, ['nop'])
24+
self.assertFalse(blks[1] in blks[0].goes_to)
25+
self.assertFalse(blks[0] in blks[1].comes_from)
26+
27+
def test_block_partition_call(self):
28+
code = """
29+
nop
30+
call __UNKNOWN
31+
nop
32+
"""
33+
self.blk.code = [x for x in code.split('\n') if x.strip()]
34+
blks = basicblock.get_basic_blocks(self.blk)
35+
self.assertEqual(len(blks), 2)
36+
self.assertEqual(blks[0].code, ['nop', 'call __UNKNOWN'])
37+
self.assertEqual(blks[1].code, ['nop'])
38+
self.assertFalse(blks[1] in blks[0].goes_to)
39+
self.assertFalse(blks[0] in blks[1].comes_from)
40+
41+
def test_block_partition_jp_flag(self):
42+
code = """
43+
nop
44+
jp z, __UNKNOWN
45+
nop
46+
"""
47+
self.blk.code = [x for x in code.split('\n') if x.strip()]
48+
blks = basicblock.get_basic_blocks(self.blk)
49+
self.assertEqual(len(blks), 2)
50+
self.assertEqual(blks[0].code, ['nop', 'jp z, __UNKNOWN'])
51+
self.assertEqual(blks[1].code, ['nop'])
52+
self.assertTrue(blks[1] in blks[0].goes_to)
53+
self.assertTrue(blks[0] in blks[1].comes_from)
54+
55+
def test_block_partition_call_flag(self):
56+
code = """
57+
nop
58+
call z, __UNKNOWN
59+
nop
60+
"""
61+
self.blk.code = [x for x in code.split('\n') if x.strip()]
62+
blks = basicblock.get_basic_blocks(self.blk)
63+
self.assertEqual(len(blks), 2)
64+
self.assertEqual(blks[0].code, ['nop', 'call z, __UNKNOWN'])
65+
self.assertEqual(blks[1].code, ['nop'])
66+
self.assertTrue(blks[1] in blks[0].goes_to)
67+
self.assertTrue(blks[0] in blks[1].comes_from)

0 commit comments

Comments
 (0)