fix broken optimization for wordvar - value expressions

This commit is contained in:
Irmen de Jong
2025-09-09 07:18:18 +02:00
parent d4c460072b
commit ced4c5944a
6 changed files with 40 additions and 35 deletions

View File

@@ -1438,27 +1438,29 @@ internal class AssignmentAsmGen(
} else if(dt.isWord || dt.isPointer) { } else if(dt.isWord || dt.isPointer) {
fun doAddOrSubWordExpr() { fun doAddOrSubWordExpr() {
if(expr.left is PtIdentifier) { if(expr.operator=="+" && expr.left.type.isWord && expr.left is PtIdentifier) {
val symname = asmgen.asmVariableName(expr.left as PtIdentifier) val symname = asmgen.asmVariableName(expr.left as PtIdentifier)
assignExpressionToRegister(expr.right, RegisterOrPair.AY, dt.isSigned) assignExpressionToRegister(expr.right, RegisterOrPair.AY, expr.right.type.isSigned)
if(expr.operator=="+") asmgen.out("""
asmgen.out(""" clc
clc adc $symname
adc $symname tax
tax tya
tya adc $symname+1
adc $symname+1 tay
tay txa""")
txa""") }
else else if(expr.operator=="-" && expr.right.type.isWord && expr.right is PtIdentifier) {
asmgen.out(""" val symname = asmgen.asmVariableName(expr.right as PtIdentifier)
sec assignExpressionToRegister(expr.left, RegisterOrPair.AY, expr.left.type.isSigned)
sbc $symname asmgen.out("""
tax sec
tya sbc $symname
sbc $symname+1 tax
tay tya
txa""") sbc $symname+1
tay
txa""")
} else { } else {
asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1") asmgen.assignWordOperandsToAYAndVar(expr.left, expr.right, "P8ZP_SCRATCH_W1")
if(expr.operator=="+") if(expr.operator=="+")
@@ -1603,7 +1605,7 @@ internal class AssignmentAsmGen(
if(right.type.isSigned) { if(right.type.isSigned) {
// we need to sign extend, do this via temporary word variable // we need to sign extend, do this via temporary word variable
asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W1", DataType.WORD) asmgen.assignExpressionToVariable(right, "P8ZP_SCRATCH_W1", DataType.WORD)
assignExpressionToRegister(left, RegisterOrPair.AY, dt.isSigned) assignExpressionToRegister(left, RegisterOrPair.AY, left.type.isSigned)
if(expr.operator=="+") { if(expr.operator=="+") {
asmgen.out(""" asmgen.out("""
clc clc
@@ -1624,7 +1626,7 @@ internal class AssignmentAsmGen(
txa""") txa""")
} }
} else { } else {
assignExpressionToRegister(left, RegisterOrPair.AY, dt.isSigned) assignExpressionToRegister(left, RegisterOrPair.AY, left.type.isSigned)
val castedSymname = asmgen.asmVariableName(castedValue) val castedSymname = asmgen.asmVariableName(castedValue)
if (expr.operator == "+") if (expr.operator == "+")
asmgen.out(""" asmgen.out("""

View File

@@ -243,9 +243,9 @@ class Inliner(private val program: Program, private val options: CompilationOpti
} }
private fun canInline(sub: Subroutine, fcall: IFunctionCall): Boolean { private fun canInline(sub: Subroutine, fcall: IFunctionCall): Boolean {
if(!sub.inline) if (!sub.inline)
return false return false
if(options.compTarget.name!=VMTarget.NAME) { if (options.compTarget.name != VMTarget.NAME) {
val stmt = sub.statements.single() val stmt = sub.statements.single()
if (stmt is IFunctionCall) { if (stmt is IFunctionCall) {
val existing = (fcall as Node).definingScope.lookup(stmt.target.nameInSource.take(1)) val existing = (fcall as Node).definingScope.lookup(stmt.target.nameInSource.take(1))

View File

@@ -44,7 +44,7 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> { override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
// Most code generation targets only support subroutine inlining on asmsub subroutines // Most code generation targets only support subroutine inlining on asmsub subroutines
// So we reset the flag here to be sure it doesn't cause problems down the line in the codegen. // So we reset the flag here to be sure it doesn't cause problems down the line in the codegen.
if(!subroutine.isAsmSubroutine && options.compTarget.name!=VMTarget.NAME) if(!subroutine.isAsmSubroutine && options.compTarget.name != VMTarget.NAME)
subroutine.inline = false subroutine.inline = false
val mods = mutableListOf<IAstModification>() val mods = mutableListOf<IAstModification>()
@@ -205,7 +205,7 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
} }
if(expr.operator=="+" || expr.operator=="-") { if(expr.operator=="+" || expr.operator=="-") {
if(options.compTarget.name!=VMTarget.NAME && expr.left.inferType(program).isPointer) { if(options.compTarget.name != VMTarget.NAME && expr.left.inferType(program).isPointer) {
val cast = expr.right as? TypecastExpression val cast = expr.right as? TypecastExpression
if(cast!=null && cast.type.isWord && cast.expression.inferType(program).isBytes) { if(cast!=null && cast.type.isWord && cast.expression.inferType(program).isBytes) {
val structsize = expr.left.inferType(program).getOrUndef().size(program.memsizer) val structsize = expr.left.inferType(program).getOrUndef().size(program.memsizer)

View File

@@ -1,8 +1,7 @@
TODO TODO
==== ====
SIZE REGRESSION: rockrunner is a bit larger than with 11.4.1 SIZE REGRESSION: rockrunner is a few dozen bytes larger than with 11.4.1
BUG: rockrunner level exit sound doesn't play anymore (11.4.1 was still ok) (can test with demo and warp)
not all source lines are correctly reported in the IR file, not all source lines are correctly reported in the IR file,

View File

@@ -1,10 +1,14 @@
main { %import textio
struct element { %zeropage basicsafe
word y
}
main {
sub start() { sub start() {
^^element zp_element = 20000 uword @shared z = 100
zp_element.y = cx16.r0L as byte ubyte @shared x = 200
for x in 15 downto 1 {
txt.print_uw(x*$0002-z) ; TODO fix 6502 optimization bug
txt.nl()
}
} }
} }

View File

@@ -111,7 +111,7 @@ private fun optimizeBinaryExpressions(program: PtProgram, options: CompilationOp
val typecast=node.left as? PtTypeCast val typecast=node.left as? PtTypeCast
if(typecast!=null && typecast.type.isWord && typecast.value is PtIdentifier) { if(typecast!=null && typecast.type.isWord && typecast.value is PtIdentifier) {
val addition = node.parent as? PtBinaryExpression val addition = node.parent as? PtBinaryExpression
if(addition!=null && (addition.operator=="+" || addition.operator=="-") && addition.type.isWord) { if(addition!=null && addition.operator=="+" && addition.type.isWord) {
// word + (byte<<1 as uword) (== word + byte*2) --> (word + (byte as word)) + (byte as word) // word + (byte<<1 as uword) (== word + byte*2) --> (word + (byte as word)) + (byte as word)
val parent = addition.parent val parent = addition.parent
val index = parent.children.indexOf(addition) val index = parent.children.indexOf(addition)