fix const value of AddressOf for certain types

This commit is contained in:
Irmen de Jong 2024-01-09 22:10:25 +01:00
parent 38dc7fb7bd
commit f27e3478b9
7 changed files with 63 additions and 13 deletions

View File

@ -20,6 +20,11 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
private val evaluator = ConstExprEvaluator()
override fun after(addressOf: AddressOf, parent: Node): Iterable<IAstModification> {
val constAddr = addressOf.constValue(program) ?: return noModifications
return listOf(IAstModification.ReplaceNode(addressOf, constAddr, parent))
}
override fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> {
// @( &thing ) --> thing (but only if thing is a byte type!)
val addrOf = memread.addressExpression as? AddressOf
@ -432,6 +437,11 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
return noModifications
}
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
val constValue = typecast.constValue(program) ?: return noModifications
return listOf(IAstModification.ReplaceNode(typecast, constValue, parent))
}
private class ShuffleOperands(val expr: BinaryExpression,
val exprOperator: String?,
val subExpr: BinaryExpression,

View File

@ -43,6 +43,10 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
}
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
val constValue = typecast.constValue(program)
if(constValue!=null)
return listOf(IAstModification.ReplaceNode(typecast, constValue, parent))
if(typecast.expression is NumericLiteral) {
val value = (typecast.expression as NumericLiteral).cast(typecast.type)
if(value.isValid)

View File

@ -271,4 +271,27 @@ main {
(assignv2 as NumericLiteral).number shouldBe 0.0
}
test("const address-of memory mapped arrays") {
val src="""
main {
sub start() {
&uword[30] wb = ${'$'}2000
&uword[100] array1 = ${'$'}9e00
&uword[30] array2 = &array1[len(wb)]
cx16.r0 = &array1 ; ${'$'}9e00
cx16.r1 = &array1[len(wb)] ; ${'$'}9e3c
cx16.r2 = &array2 ; ${'$'}9e3c
}
}"""
val result = compileText(Cx16Target(), false, src, writeAssembly = false)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 6
((st[0] as VarDecl).value as NumericLiteral).number shouldBe 0x2000
((st[1] as VarDecl).value as NumericLiteral).number shouldBe 0x9e00
((st[2] as VarDecl).value as NumericLiteral).number shouldBe 0x9e00+2*30
((st[3] as Assignment).value as NumericLiteral).number shouldBe 0x9e00
((st[4] as Assignment).value as NumericLiteral).number shouldBe 0x9e00+2*30
((st[5] as Assignment).value as NumericLiteral).number shouldBe 0x9e00+2*30
}
})

View File

@ -444,7 +444,11 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
override fun visit(addressOf: AddressOf) {
output("&")
addressOf.identifier.accept(this)
addressOf.arrayIndex?.accept(this)
if(addressOf.arrayIndex!=null) {
output("[")
addressOf.arrayIndex?.accept(this)
output("]")
}
}
override fun visit(inlineAssembly: InlineAssembly) {

View File

@ -408,9 +408,17 @@ data class AddressOf(var identifier: IdentifierReference, var arrayIndex: ArrayI
override fun constValue(program: Program): NumericLiteral? {
val target = this.identifier.targetStatement(program) as? VarDecl
if(target?.type==VarDeclType.MEMORY) {
val address = target.value?.constValue(program)
if(address!=null)
return NumericLiteral(DataType.UWORD, address.number, position)
var address = target.value?.constValue(program)?.number
if(address!=null) {
if(arrayIndex!=null) {
val index = arrayIndex?.constIndex()
if (index != null)
address += program.memsizer.memorySize(target.datatype, index)
else
return null
}
return NumericLiteral(DataType.UWORD, address, position)
}
}
return null
}

View File

@ -3,6 +3,8 @@ TODO
IR: use SCC and SCS, to optimize some code that sets 0/1 based on carry flag status
try to get rid of ArrayIndex class
...

View File

@ -1,17 +1,16 @@
%import floats
%import textio
%zeropage basicsafe
%option no_sysinit
mpb {
const uword HIGH_MEMORY_START = $A000
}
main {
&uword[20] wa = mpb.HIGH_MEMORY_START
; &uword[20] wa = $A000
sub start() {
wa[0] = "smile"
txt.print(wa[0])
&uword[30] wb = $2000
&uword[100] array1 = $9e00
&uword[30] array2 = &array1[len(wb)]
txt.print_uwhex(&array1, true) ; $9e00
txt.print_uwhex(&array1[len(wb)], true) ; $9e3c
txt.print_uwhex(&array2, true) ; $9e3c
}
}