mirror of
https://github.com/irmen/prog8.git
synced 2025-01-27 10:31:40 +00:00
fixes
This commit is contained in:
parent
4dc214199f
commit
890fcffdfa
@ -58,6 +58,9 @@ def generate_aug_assignment(ctx: Context) -> None:
|
||||
raise CodeError("cannot assign a combined 16-bit register to a single 8-bit register", rvalue)
|
||||
_generate_aug_reg_reg(out, lvalue, stmt.operator, rvalue, ctx.scope)
|
||||
elif isinstance(rvalue, Dereference):
|
||||
print("warning: {}: using indirect/dereferece is very costly".format(rvalue.sourceref))
|
||||
if rvalue.datatype != DataType.BYTE:
|
||||
raise CodeError("aug. assignment value must be a byte, 0..255", rvalue)
|
||||
if isinstance(rvalue.operand, (LiteralValue, SymbolName)):
|
||||
if isinstance(rvalue.operand, LiteralValue):
|
||||
what = to_hex(rvalue.operand.value)
|
||||
@ -75,14 +78,22 @@ def generate_aug_assignment(ctx: Context) -> None:
|
||||
out("\vldy #0")
|
||||
out("\vlda (il65_lib.SCRATCH_ZPWORD1), y")
|
||||
a_reg = Register(name="A", sourceref=stmt.sourceref) # type: ignore
|
||||
if 'A' in lvalue.name:
|
||||
raise CodeError("can't yet use register A in this aug assign lhs", lvalue.sourceref) # @todo
|
||||
_generate_aug_reg_reg(out, lvalue, stmt.operator, a_reg, ctx.scope)
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
if lvalue.name in REGISTER_BYTES:
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
else:
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name[0].lower()))
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||
out("\vpla\n\vtay\n\vpla") # restore A, Y from stack
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
if lvalue.name in REGISTER_BYTES:
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
else:
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[0].lower()))
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||
elif isinstance(rvalue.operand, Register):
|
||||
assert rvalue.operand.datatype == DataType.WORD
|
||||
if rvalue.datatype != DataType.BYTE:
|
||||
raise CodeError("aug. assignment value must be a byte, 0..255", rvalue)
|
||||
reg = rvalue.operand.name
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZPWORD1".format(reg[0].lower()))
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZPWORD1+1".format(reg[1].lower()))
|
||||
@ -90,12 +101,22 @@ def generate_aug_assignment(ctx: Context) -> None:
|
||||
out("\vldy #0")
|
||||
out("\vlda (il65_lib.SCRATCH_ZPWORD1), y")
|
||||
a_reg = Register(name="A", sourceref=stmt.sourceref) # type: ignore
|
||||
if 'A' in lvalue.name:
|
||||
raise CodeError("can't yet use register A in this aug assign lhs", lvalue.sourceref) # @todo
|
||||
_generate_aug_reg_reg(out, lvalue, stmt.operator, a_reg, ctx.scope)
|
||||
if lvalue.name != 'X':
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
if lvalue.name in REGISTER_BYTES:
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
else:
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name[0].lower()))
|
||||
out("\vst{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||
out("\vpla\n\vtay\n\vpla") # restore A, Y from stack
|
||||
if lvalue.name != 'X':
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
if lvalue.name in REGISTER_BYTES:
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name.lower()))
|
||||
else:
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP1".format(lvalue.name[0].lower()))
|
||||
out("\vld{:s} il65_lib.SCRATCH_ZP2".format(lvalue.name[1].lower()))
|
||||
else:
|
||||
raise CodeError("invalid dereference operand type", rvalue)
|
||||
else:
|
||||
@ -109,7 +130,7 @@ def _generate_aug_reg_int(out: Callable, lvalue: Register, operator: str, rvalue
|
||||
right_str = rname
|
||||
else:
|
||||
# an immediate value is provided in rvalue
|
||||
right_str = "#" + to_hex(rvalue)
|
||||
right_str = "#" + str(rvalue)
|
||||
if operator == "+=":
|
||||
_gen_aug_plus_reg_int(lvalue, out, right_str, scope)
|
||||
elif operator == "-=":
|
||||
@ -125,7 +146,8 @@ def _generate_aug_reg_int(out: Callable, lvalue: Register, operator: str, rvalue
|
||||
elif operator == "<<=":
|
||||
_gen_aug_shiftleft_reg_int(lvalue, out, rname, rvalue, scope)
|
||||
else:
|
||||
raise ValueError("invalid operator", operator)
|
||||
# @todo implement more operators such as *= /=
|
||||
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref))
|
||||
|
||||
|
||||
def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue: Register, scope: Scope) -> None:
|
||||
@ -144,7 +166,8 @@ def _generate_aug_reg_reg(out: Callable, lvalue: Register, operator: str, rvalue
|
||||
elif operator == "<<=":
|
||||
_gen_aug_shiftleft_reg_reg(lvalue, out, rvalue, scope)
|
||||
else:
|
||||
raise ValueError("invalid operator", operator)
|
||||
# @todo implement more operators such as *= /=
|
||||
raise ValueError("invalid operator: " + operator, str(lvalue.sourceref))
|
||||
|
||||
|
||||
def _gen_aug_shiftleft_reg_int(lvalue: Register, out: Callable, rname: str, rvalue: int, scope: Scope) -> None:
|
||||
@ -304,8 +327,29 @@ def _gen_aug_minus_reg_int(lvalue: Register, out: Callable, right_str: str, scop
|
||||
out("\vsec")
|
||||
out("\vsbc " + right_str)
|
||||
out("\vtay")
|
||||
elif lvalue.name == "AX":
|
||||
out("\vsec")
|
||||
out("\vsbc " + right_str)
|
||||
out("\vbcs +")
|
||||
out("\vdex")
|
||||
out("+")
|
||||
elif lvalue.name == "AY":
|
||||
out("\vsec")
|
||||
out("\vsbc " + right_str)
|
||||
out("\vbcs +")
|
||||
out("\vdey")
|
||||
out("+")
|
||||
elif lvalue.name == "XY":
|
||||
with preserving_registers({'A'}, scope, out):
|
||||
out("\vtxa")
|
||||
out("\vsec")
|
||||
out("\vsbc " + right_str)
|
||||
out("\vtax")
|
||||
out("\vbcs +")
|
||||
out("\vdey")
|
||||
out("+")
|
||||
else:
|
||||
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo -=.word
|
||||
raise ValueError("invalid register", str(lvalue))
|
||||
|
||||
|
||||
def _gen_aug_plus_reg_int(lvalue: Register, out: Callable, right_str: str, scope: Scope) -> None:
|
||||
@ -324,8 +368,29 @@ def _gen_aug_plus_reg_int(lvalue: Register, out: Callable, right_str: str, scope
|
||||
out("\vclc")
|
||||
out("\vadc " + right_str)
|
||||
out("\vtay")
|
||||
elif lvalue.name == "AX":
|
||||
out("\vclc")
|
||||
out("\vadc " + right_str)
|
||||
out("\vbcc +")
|
||||
out("\vinx")
|
||||
out("+")
|
||||
elif lvalue.name == "AY":
|
||||
out("\vclc")
|
||||
out("\vadc " + right_str)
|
||||
out("\vbcc +")
|
||||
out("\viny")
|
||||
out("+")
|
||||
elif lvalue.name == "XY":
|
||||
with preserving_registers({'A'}, scope, out):
|
||||
out("\vtxa")
|
||||
out("\vclc")
|
||||
out("\vadc " + right_str)
|
||||
out("\vtax")
|
||||
out("\vbcc +")
|
||||
out("\viny")
|
||||
out("+")
|
||||
else:
|
||||
raise CodeError("unsupported register for aug assign", str(lvalue)) # @todo +=.word
|
||||
raise ValueError("invalid register", str(lvalue))
|
||||
|
||||
|
||||
def _gen_aug_shiftleft_reg_reg(lvalue: Register, out: Callable, rvalue: Register, scope: Scope) -> None:
|
||||
@ -466,23 +531,42 @@ def _gen_aug_minus_reg_reg(lvalue: Register, out: Callable, rvalue: Register, sc
|
||||
def _gen_aug_plus_reg_reg(lvalue: Register, out: Callable, rvalue: Register, scope: Scope) -> None:
|
||||
if rvalue.name not in REGISTER_BYTES:
|
||||
raise CodeError("unsupported rvalue register for aug assign", str(rvalue)) # @todo +=.word
|
||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
||||
if lvalue.name == "A":
|
||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
||||
out("\vclc")
|
||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||
elif lvalue.name == "X":
|
||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
||||
with preserving_registers({'A'}, scope, out):
|
||||
out("\vtxa")
|
||||
out("\vclc")
|
||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||
out("\vtax")
|
||||
elif lvalue.name == "Y":
|
||||
out("\vst{:s} {:s}".format(rvalue.name.lower(), to_hex(Zeropage.SCRATCH_B1)))
|
||||
with preserving_registers({'A'}, scope, out):
|
||||
out("\vtya")
|
||||
out("\vclc")
|
||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||
out("\vtay")
|
||||
elif lvalue.name == "AX":
|
||||
out("\vclc")
|
||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||
out("\vbcc +")
|
||||
out("\vinx")
|
||||
out("+")
|
||||
elif lvalue.name == "AY":
|
||||
out("\vclc")
|
||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||
out("\vbcc +")
|
||||
out("\viny")
|
||||
out("+")
|
||||
elif lvalue.name == "XY":
|
||||
with preserving_registers({'A'}, scope, out):
|
||||
out("\vtxa")
|
||||
out("\vclc")
|
||||
out("\vadc " + to_hex(Zeropage.SCRATCH_B1))
|
||||
out("\vtax")
|
||||
out("\vbcc +")
|
||||
out("\viny")
|
||||
out("+")
|
||||
else:
|
||||
raise CodeError("unsupported lvalue register for aug assign", str(lvalue)) # @todo +=.word
|
||||
raise ValueError("invalid register", str(lvalue))
|
||||
|
9
todo.ill
9
todo.ill
@ -3,11 +3,10 @@
|
||||
|
||||
~ main {
|
||||
|
||||
;var .float flt
|
||||
; var bytevar = 22 + 23 ; @todo constant-fold before semantic check
|
||||
; var .float initfloat1 = -1.234e-14 ; @todo constant-fold before semantic check / fix float parse?
|
||||
; var .float initfloat2 = -555.666 ; @todo constant-fold before semantic check / fix float parse?
|
||||
; var .text guess = '?' * 80 ; @todo constant-fold before semantic check
|
||||
var .float flt
|
||||
var bytevar = 22 + 23 ; @todo bytevar in source should show its initial value in a comment
|
||||
var .text guess1 = "?X" * 40 ; @todo constant-fold before semantic check
|
||||
var .text guess2 = "?" * 40 ; @todo string result instead of int!
|
||||
const .word border = $d020
|
||||
var .word border2 = $d020
|
||||
memory screenm = $d021
|
||||
|
50
todo2.ill
50
todo2.ill
@ -39,11 +39,11 @@ start:
|
||||
|
||||
X += border
|
||||
XY += border ; @todo .word augassign register
|
||||
XY -= 1234+333 ; @todo .word augassign register
|
||||
XY -= 234+3 ; @todo .word augassign register
|
||||
|
||||
A += [c2f]
|
||||
AY += [c2f]
|
||||
AY += [XY]
|
||||
X += [c2f]
|
||||
XY += [c2f]
|
||||
Y += [XY]
|
||||
|
||||
XY+=255
|
||||
XY+=254
|
||||
@ -53,21 +53,21 @@ start:
|
||||
XY-=253
|
||||
|
||||
v3t++
|
||||
v3t+=1
|
||||
v3t+=1 ; @todo? (optimize) join with previous
|
||||
v3t+=0 ; is removed.
|
||||
v3t+=1 ; @todo? (optimize) join with previous
|
||||
v3t+=1 ; @todo? (optimize) join with previous
|
||||
v3t=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
v3t=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||
v3t=1.23411 + 1; @todo store as constant float with generated name, replace value node
|
||||
v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||
v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||
v3t=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
||||
XY*=2
|
||||
XY*=3
|
||||
;v3t+=1 ; @todo non-reg augassign
|
||||
;v3t+=1 ; @todo? (optimize) join with previous
|
||||
;v3t+=0 ; is removed by optimizer
|
||||
;v3t+=1 ; @todo? (optimize) join with previous
|
||||
;v3t+=1 ; @todo? (optimize) join with previous
|
||||
;v3t=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
;v3t=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||
;v3t=1.23411 + 1; @todo store as constant float with generated name, replace value node
|
||||
;v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
;v3t+=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
;v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||
;v3t+=2.23411 ; @todo store as constant float with generated name, replace value node
|
||||
;v3t=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
||||
;XY*=2 ; @todo operator
|
||||
;XY*=3 ; @todo operator
|
||||
X=3 ; @todo optimize consecutive assignments
|
||||
X=4
|
||||
X=5
|
||||
@ -83,11 +83,11 @@ start:
|
||||
border = 1
|
||||
border = 2
|
||||
|
||||
XY=XY/0 ; @todo zerodiv (during expression to code generation)
|
||||
XY=XY//0 ; @todo zerodiv (during expression to code generation)
|
||||
XY*=2.23424 ; @todo store as constant float with generated name, replace value node
|
||||
XY*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
||||
v3t*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node
|
||||
;XY=XY/0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||
;XY=XY//0 ; @todo zerodiv (during expression to code generation) @todo operator
|
||||
;XY*=2.23424 ; @todo store as constant float with generated name, replace value node @todo operator
|
||||
;XY*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node @todo operator
|
||||
;v3t*=2.23424 * v3t ; @todo store as constant float with generated name, replace value node @todo operator, non-register
|
||||
A++
|
||||
X--
|
||||
A+=1
|
||||
@ -104,7 +104,7 @@ start:
|
||||
A+=3
|
||||
XY+=6
|
||||
XY+=222
|
||||
XY+=666
|
||||
XY+=11
|
||||
|
||||
return 44
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user