Skip to content

Commit aefd42c

Browse files
committed
Use binary search to find memory slot. A few fixes to the compiler.
1 parent 6e112ef commit aefd42c

File tree

3 files changed

+141
-80
lines changed

3 files changed

+141
-80
lines changed

compiler/asm_extensions.py

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,89 @@ def __init__(self, pos, writer, namespace, page_size=64, **kwargs):
1515
self.add_page()
1616

1717
def add_page(self):
18-
setter = Subsequence()
19-
getter = Subsequence()
20-
dump = ["["]
21-
2218
mbr = Var('memory_buffer')
2319
mar = Var('memory_address')
2420

25-
for i in range(self.page_size):
26-
slot = Var('memory_slot', i)
27-
dump.append(slot)
28-
if i != self.page_size - 1:
29-
dump.append(",")
21+
def pair_name(fn, pair):
22+
return 'memory/%s_%d_%d' % (fn, pair.min, pair.max)
3023

31-
setter.add_command(OpAssign(slot, mbr).where(SelEquals(mar, i)))
32-
getter.add_command(OpAssign(mbr, slot).where(SelEquals(mar, i)))
24+
def create_function(pair, force=False):
25+
getter = Subsequence()
26+
setter = Subsequence()
27+
def gen_fn(fn, p):
28+
return Function(pair_name(fn, p), cond_type='if',
29+
cond=SelRange(mar, min=p.min, max=p.max))
30+
def gen_assign(n, g=True):
31+
slot = Var('memory_slot', n)
32+
return OpAssign(mbr if g else slot, slot if g else mbr) \
33+
.where(SelEquals(mar, n))
3334

34-
self.scope.add_function_names(('mem_set', 'mem_get', 'mem_dump'))
35-
self.add_subsequence('mem_set', setter)
35+
if pair.left and pair.left.left:
36+
getter.add_command(gen_fn('mem_get', pair.left))
37+
setter.add_command(gen_fn('mem_set', pair.left))
38+
if pair.right and pair.right.right:
39+
getter.add_command(gen_fn('mem_get', pair.right))
40+
setter.add_command(gen_fn('mem_set', pair.right))
41+
42+
if not pair.left and not pair.right and not force:
43+
# Don't do anything here, it's done in the next level up
44+
return
45+
46+
if pair.left and not pair.left.left or force:
47+
getter.add_command(gen_assign(pair.min))
48+
setter.add_command(gen_assign(pair.min, False))
49+
if pair.right and not pair.right.right:
50+
getter.add_command(gen_assign(pair.max))
51+
setter.add_command(gen_assign(pair.max, False))
52+
53+
name_get = pair_name('mem_get', pair)
54+
name_set = pair_name('mem_set', pair)
55+
self.scope.add_function_names((name_get, name_set))
56+
self.add_subsequence(name_get, getter)
57+
self.add_subsequence(name_set, setter)
58+
59+
entry_point = self.generate_bin_tree(self.page_size, create_function)
60+
if not entry_point.left and not entry_point.right:
61+
create_function(entry_point, force=True)
62+
63+
# Redirect mem_get and mem_set to the actual entry point
64+
getter = Subsequence()
65+
setter = Subsequence()
66+
getter.add_command(Function(pair_name('mem_get', entry_point)))
67+
setter.add_command(Function(pair_name('mem_set', entry_point)))
68+
self.scope.add_function_names(('mem_get', 'mem_set'))
3669
self.add_subsequence('mem_get', getter)
37-
s = Subsequence()
38-
dump.append("]")
39-
s.add_command(Tellraw(dump, 'a'))
40-
self.add_subsequence('mem_dump', s)
70+
self.add_subsequence('mem_set', setter)
71+
72+
73+
def generate_bin_tree(self, size, callback):
74+
assert size > 0
75+
from collections import namedtuple
76+
Pair = namedtuple('Pair', 'left right min max')
77+
old_pairs = []
78+
for n in range(size):
79+
pair = Pair(None, None, n, n)
80+
old_pairs.append(pair)
81+
callback(pair)
82+
while len(old_pairs) > 1:
83+
pairs = []
84+
waiting = None
85+
for pair in old_pairs:
86+
if waiting is None:
87+
waiting = pair
88+
else:
89+
new_pair = Pair(waiting, pair, waiting.min, pair.max)
90+
pairs.append(new_pair)
91+
callback(new_pair)
92+
waiting = None
93+
94+
if waiting is not None:
95+
# Dangling node, occurs if size is not a power of 2
96+
pairs.append(waiting)
97+
callback(waiting)
98+
99+
old_pairs = pairs
100+
return old_pairs[0]
41101

42102
def extended_setup(self, up, down):
43103
for i in range(self.page_size):

0 commit comments

Comments
 (0)