Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
from src.api import errors # noqa
from src.api import errmsg # noqa
from src.api import utils # noqa
from src.api import symboltable # noqa
7 changes: 2 additions & 5 deletions src/api/symboltable.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,9 +533,6 @@ def access_call(self, id_: str, lineno: int, scope=None, type_=None):
entry.callable = False
return entry

# Mangled name (functions always has _name as mangled)
# entry.mangled = '_%s' % entry.name
# entry.callable = True # HINT: must be true already
return entry

def access_label(self, id_: str, lineno: int, scope: Optional[Scope] = None):
Expand Down Expand Up @@ -691,7 +688,7 @@ def declare_label(self, id_: str, lineno: int) -> Optional[SymbolLABEL]:
# Just the label, because it starts with '.' so it's a root-global label
entry.mangled = f'{id_}'
else:
# TODO: This shouln't be needed (but still is). Need investigation
# TODO: This shouldn't be needed (but still is). Need investigation
entry.mangled = f'{global_.LABELS_NAMESPACE}.{symbols.LABEL.prefix}{entry.name}'

entry.is_line_number = isinstance(id1, int)
Expand Down Expand Up @@ -720,7 +717,7 @@ def declare_param(self, id_: str, lineno: int, type_=None, is_array=False) -> Op
entry = self.declare(id_, lineno, symbols.PARAMDECL(id_, lineno, type_))

if entry is None:
return
return None

entry.declared = True
if entry.type_.implicit:
Expand Down
8 changes: 6 additions & 2 deletions src/arch/zx48k/optimizer/basicblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,18 +381,22 @@ def is_used(self, regs, i, top=None):
top -= 1

if regs and regs[0][0] == '(' and regs[0][-1] == ')': # A memory address
r16 = helpers.single_registers(regs[0][1:-1])\
r16 = helpers.single_registers(regs[0][1:-1]) \
if helpers.is_16bit_oper_register(regs[0][1:-1]) else []
ix = helpers.single_registers(helpers.idx_args(regs[0][1:-1])[0]) \
if helpers.idx_args(regs[0][1:-1]) else []

rr = set(r16 + ix)
mem_vars = set([] if rr else RE_ID_OR_NUMBER.findall(regs[0]))

for mem in self[i:top]: # For memory accesses only mark as NOT uses if it's overwritten
for mem in self[i:top]: # For memory accesses only mark as NOT used if it's overwritten
if mem.inst == 'ld' and mem.opers[0] == regs[0]:
return False

# And, Or, Xor uses both operands
if mem.inst in {'and', 'or', 'xor'} and mem.opers[0] == regs[0]:
return True

if mem.opers and mem.opers[-1] == regs[0]:
return True

Expand Down
5 changes: 2 additions & 3 deletions src/arch/zx48k/peephole/opts/109_o4_ld_mem_op_ld_mem.opt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
;; Removes useless LD's
;; Tries to guess the value of the 1st and 2nd operands.
;; If they're the same, this LD is useless
;; Removes useless operation
;; Tries to guess if the result of the operation LD, OR, AND, XOR, ADC, ADD, SBC is later used

OLEVEL: 4
OFLAG: 109
Expand Down
2 changes: 1 addition & 1 deletion src/zxbc/zxbparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ def p_var_decl_at(p):
if entry is None:
return

if p[5].token in 'CONST':
if p[5].token == 'CONST':
tmp = p[5].expr
if tmp.token == 'UNARY' and tmp.operator == 'ADDRESS': # Must be an ID
if tmp.operand.token in ('VAR', 'LABEL'):
Expand Down
24 changes: 24 additions & 0 deletions tests/arch/zx48k/optimizer/test_basicblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,27 @@ def test_mempos_requires(self):
"""
self.blk.code = [x for x in code.split('\n') if x.strip()]
self.assertTrue(self.blk.is_used(['(_k)'], 0))

def test_is_used_or_ix(self):
code = """
or (ix-1)
ld (ix-1), a
"""
self.blk.code = [x for x in code.split('\n') if x.strip()]
assert self.blk.is_used(['(ix-1)'], 0)

def test_is_used_and_ix(self):
code = """
and (ix-1)
ld (ix-1), a
"""
self.blk.code = [x for x in code.split('\n') if x.strip()]
assert self.blk.is_used(['(ix-1)'], 0)

def test_is_used_xor_ix(self):
code = """
xor (ix-1)
ld (ix-1), a
"""
self.blk.code = [x for x in code.split('\n') if x.strip()]
assert self.blk.is_used(['(ix-1)'], 0)
54 changes: 54 additions & 0 deletions tests/functional/opt4_due0.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
org 32768
.core.__START_PROGRAM:
di
push ix
push iy
exx
push hl
exx
ld hl, 0
add hl, sp
ld (.core.__CALL_BACK__), hl
ei
jp .core.__MAIN_PROGRAM__
.core.__CALL_BACK__:
DEFW 0
.core.ZXBASIC_USER_DATA:
; Defines USER DATA Length in bytes
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
.core.ZXBASIC_USER_DATA_END:
.core.__MAIN_PROGRAM__:
call _Demo_PutPlayer
ld b, h
ld c, l
.core.__END_PROGRAM:
di
ld hl, (.core.__CALL_BACK__)
ld sp, hl
exx
pop hl
pop iy
pop ix
exx
ei
ret
_Demo_PutPlayer:
push ix
ld ix, 0
add ix, sp
ld hl, 0
push hl
ld a, (ix-1)
and 199
ld (ix-1), a
ld a, (ix-2)
or (ix-1)
ld (ix-1), a
_Demo_PutPlayer__leave:
ld sp, ix
pop ix
ret
;; --- end of user code ---
END
9 changes: 9 additions & 0 deletions tests/functional/opt4_due0.bas
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sub Demo_PutPlayer()
dim atrSprite, atrGame as ubyte

atrSprite=atrSprite bAND %11000111
atrSprite=atrGame bOR atrSprite
end sub

Demo_PutPlayer()