Skip to content

Commit a707183

Browse files
committed
feat: const-fold associative operations
1 parent b34c35f commit a707183

4 files changed

Lines changed: 163 additions & 1 deletion

File tree

src/api/optimize.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,46 @@ def visit_ADDRESS(self, node):
220220
yield node
221221

222222
def visit_BINARY(self, node: symbols.BINARY):
223+
if self.O_LEVEL > 1 and node.operator in ("PLUS", "MUL"):
224+
if node.left.token == "BINARY" and node.left.operator == node.operator and chk.is_number(node.right):
225+
left = ll = None
226+
if chk.is_number(node.left.right):
227+
left = node.left.left
228+
ll = node.left.right
229+
elif chk.is_number(node.left.left):
230+
left = node.left.right
231+
ll = node.left.left
232+
233+
if left is not None:
234+
right = yield symbols.BINARY.make_node(
235+
operator=node.operator,
236+
left=ll,
237+
right=node.right,
238+
lineno=node.lineno,
239+
func=node.func,
240+
)
241+
node.left = left
242+
node.right = right
243+
elif node.right.token == "BINARY" and node.right.operator == node.operator and chk.is_number(node.left):
244+
right = rr = None
245+
if chk.is_number(node.right.left):
246+
right = node.right.right
247+
rr = node.right.left
248+
elif chk.is_number(node.right.right):
249+
right = node.right.left
250+
rr = node.right.right
251+
252+
if right is not None:
253+
left = yield symbols.BINARY.make_node(
254+
operator=node.operator,
255+
left=node.left,
256+
right=rr,
257+
lineno=node.lineno,
258+
func=node.func,
259+
)
260+
node.left = left
261+
node.right = right
262+
223263
node = yield self.generic_visit(node) # This might convert consts to numbers if possible
224264
# Retry folding
225265
yield symbols.BINARY.make_node(node.operator, node.left, node.right, node.lineno, node.func, node.type_)

src/symbols/binary.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,4 @@ def make_node(cls, operator, left, right, lineno, func=None, type_=None):
144144
else:
145145
type_ = c_type
146146

147-
return cls(operator, a, b, type_=type_, lineno=lineno)
147+
return cls(operator, a, b, type_=type_, lineno=lineno, func=func)
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
org 32768
2+
.core.__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld hl, 0
10+
add hl, sp
11+
ld (.core.__CALL_BACK__), hl
12+
ei
13+
jp .core.__MAIN_PROGRAM__
14+
.core.__CALL_BACK__:
15+
DEFW 0
16+
.core.ZXBASIC_USER_DATA:
17+
; Defines USER DATA Length in bytes
18+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
19+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
20+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
21+
_a:
22+
DEFB 00
23+
.core.ZXBASIC_USER_DATA_END:
24+
.core.__MAIN_PROGRAM__:
25+
ld a, (_a)
26+
add a, 3
27+
ld (_a), a
28+
ld h, 6
29+
call .core.__MUL8_FAST
30+
ld (_a), a
31+
add a, 3
32+
ld (_a), a
33+
ld h, 6
34+
call .core.__MUL8_FAST
35+
ld (_a), a
36+
add a, 3
37+
ld (_a), a
38+
ld h, 6
39+
call .core.__MUL8_FAST
40+
ld (_a), a
41+
add a, 3
42+
ld (_a), a
43+
ld h, 6
44+
call .core.__MUL8_FAST
45+
ld (_a), a
46+
ld hl, 0
47+
ld b, h
48+
ld c, l
49+
.core.__END_PROGRAM:
50+
di
51+
ld hl, (.core.__CALL_BACK__)
52+
ld sp, hl
53+
exx
54+
pop hl
55+
pop iy
56+
pop ix
57+
exx
58+
ei
59+
ret
60+
;; --- end of user code ---
61+
#line 1 "/zxbasic/src/arch/zx48k/library-asm/mul8.asm"
62+
push namespace core
63+
__MUL8: ; Performs 8bit x 8bit multiplication
64+
PROC
65+
;LOCAL __MUL8A
66+
LOCAL __MUL8LOOP
67+
LOCAL __MUL8B
68+
; 1st operand (byte) in A, 2nd operand into the stack (AF)
69+
pop hl ; return address
70+
ex (sp), hl ; CALLE convention
71+
;;__MUL8_FAST: ; __FASTCALL__ entry
72+
;; ld e, a
73+
;; ld d, 0
74+
;; ld l, d
75+
;;
76+
;; sla h
77+
;; jr nc, __MUL8A
78+
;; ld l, e
79+
;;
80+
;;__MUL8A:
81+
;;
82+
;; ld b, 7
83+
;;__MUL8LOOP:
84+
;; add hl, hl
85+
;; jr nc, __MUL8B
86+
;;
87+
;; add hl, de
88+
;;
89+
;;__MUL8B:
90+
;; djnz __MUL8LOOP
91+
;;
92+
;; ld a, l ; result = A and HL (Truncate to lower 8 bits)
93+
__MUL8_FAST: ; __FASTCALL__ entry, a = a * h (8 bit mul) and Carry
94+
ld b, 8
95+
ld l, a
96+
xor a
97+
__MUL8LOOP:
98+
add a, a ; a *= 2
99+
sla l
100+
jp nc, __MUL8B
101+
add a, h
102+
__MUL8B:
103+
djnz __MUL8LOOP
104+
ret ; result = HL
105+
ENDP
106+
pop namespace
107+
#line 38 "zx48k/opt2_assoc.bas"
108+
END
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
DIM a as Ubyte
2+
3+
a = (a + 1) + 2
4+
a = (a * 2) * 3
5+
6+
a = (1 + a) + 2
7+
a = (2 * a) * 3
8+
9+
10+
a = 2 + (a + 1)
11+
a = 3 * (a * 2)
12+
13+
a = 2 + (1 + a)
14+
a = 3 * (2 * a)

0 commit comments

Comments
 (0)