mirror of
https://github.com/irmen/prog8.git
synced 2025-04-05 03:37:25 +00:00
don't remove consecutive assigns to IO space location
This commit is contained in:
parent
b526e132a7
commit
81bd5c784e
@ -62,10 +62,18 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
}
|
||||
|
||||
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
||||
val nextAssign = assignment.nextSibling() as? Assignment
|
||||
if(nextAssign!=null && nextAssign.target.isSameAs(assignment.target, program)) {
|
||||
if(!nextAssign.isAugmentable && nextAssign.value isSameAs assignment.value && assignment.value !is IFunctionCall) // don't remove function calls even when they're duplicates
|
||||
return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
// remove duplicated assignments, but not if it's a memory mapped IO register
|
||||
val isIO = try {
|
||||
assignment.target.isIOAddress(options.compTarget.machine)
|
||||
} catch (_: FatalAstException) {
|
||||
false
|
||||
}
|
||||
if(!isIO) {
|
||||
val nextAssign = assignment.nextSibling() as? Assignment
|
||||
if (nextAssign != null && nextAssign.target.isSameAs(assignment.target, program)) {
|
||||
if (!nextAssign.isAugmentable && nextAssign.value isSameAs assignment.value && assignment.value !is IFunctionCall) // don't remove function calls even when they're duplicates
|
||||
return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
}
|
||||
}
|
||||
|
||||
return noModifications
|
||||
|
@ -15,6 +15,7 @@ import prog8.ast.statements.*
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Position
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.Cx16Target
|
||||
import prog8.compiler.printProgram
|
||||
import prog8tests.helpers.*
|
||||
|
||||
@ -736,4 +737,60 @@ class TestOptimization: FunSpec({
|
||||
val stmts = result.program.entrypoint.statements
|
||||
stmts.size shouldBe 3
|
||||
}
|
||||
|
||||
test("repeated assignments to IO register should remain") {
|
||||
val srcX16="""
|
||||
main {
|
||||
sub start() {
|
||||
ubyte @shared xx
|
||||
xx = 42
|
||||
xx = 42 ; removed
|
||||
xx = 42 ; removed
|
||||
cx16.VERA_DATA0 = 0
|
||||
cx16.VERA_DATA0 = 0
|
||||
cx16.VERA_DATA0 = 0
|
||||
@($9fff) = 0
|
||||
@($9fff) = 0
|
||||
@($9fff) = 0
|
||||
return
|
||||
}
|
||||
}"""
|
||||
var result = compileText(Cx16Target(), true, srcX16, writeAssembly = true)!!
|
||||
var statements = result.program.entrypoint.statements
|
||||
statements.size shouldBe 9
|
||||
(statements[1] as Assignment).target.identifier!!.nameInSource shouldBe listOf("xx")
|
||||
(statements[2] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "VERA_DATA0")
|
||||
(statements[3] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "VERA_DATA0")
|
||||
(statements[4] as Assignment).target.identifier!!.nameInSource shouldBe listOf("cx16", "VERA_DATA0")
|
||||
(statements[5] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 0x9fff
|
||||
(statements[6] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 0x9fff
|
||||
(statements[7] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 0x9fff
|
||||
|
||||
val srcC64="""
|
||||
main {
|
||||
sub start() {
|
||||
ubyte @shared xx
|
||||
xx = 42
|
||||
xx = 42 ;removed
|
||||
xx = 42 ;removed
|
||||
c64.EXTCOL = 0
|
||||
c64.EXTCOL = 0
|
||||
c64.EXTCOL = 0
|
||||
@(53281) = 0
|
||||
@(53281) = 0
|
||||
@(53281) = 0
|
||||
return
|
||||
}
|
||||
}"""
|
||||
result = compileText(C64Target(), true, srcC64, writeAssembly = true)!!
|
||||
statements = result.program.entrypoint.statements
|
||||
statements.size shouldBe 9
|
||||
(statements[1] as Assignment).target.identifier!!.nameInSource shouldBe listOf("xx")
|
||||
(statements[2] as Assignment).target.identifier!!.nameInSource shouldBe listOf("c64", "EXTCOL")
|
||||
(statements[3] as Assignment).target.identifier!!.nameInSource shouldBe listOf("c64", "EXTCOL")
|
||||
(statements[4] as Assignment).target.identifier!!.nameInSource shouldBe listOf("c64", "EXTCOL")
|
||||
(statements[5] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 53281.0
|
||||
(statements[6] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 53281.0
|
||||
(statements[7] as Assignment).target.memoryAddress!!.addressExpression.constValue(result.program)!!.number shouldBe 53281.0
|
||||
}
|
||||
})
|
||||
|
@ -532,8 +532,7 @@ data class AssignTarget(var identifier: IdentifierReference?,
|
||||
} else false
|
||||
}
|
||||
ident != null -> {
|
||||
val decl = ident.targetVarDecl(definingModule.program) ?:
|
||||
throw FatalAstException("invalid identifier ${ident.nameInSource}")
|
||||
val decl = ident.targetVarDecl(definingModule.program) ?: throw FatalAstException("invalid identifier ${ident.nameInSource}")
|
||||
return if (decl.type == VarDeclType.MEMORY && decl.value is NumericLiteral)
|
||||
machine.isIOAddress((decl.value as NumericLiteral).number.toUInt())
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user