improved codegen for some pointer+index expressions

This commit is contained in:
Irmen de Jong 2024-07-18 23:41:34 +02:00
parent 9046fe8d3a
commit d18f2a7bfd
3 changed files with 131 additions and 9 deletions

View File

@ -314,18 +314,100 @@ internal class AssignmentAsmGen(private val program: PtProgram,
}
private fun assignByteFromAddressExpression(address: PtExpression, target: AsmAssignTarget) {
// TODO optimize this into more efficient code, using indexed register ,Y instead of explicitly calculating the full pointer value, or use self=modifying code and just use absolute addressing.
// see: https://discord.com/channels/547559626024157184/629863245934755860/1262873088782110750
if(address is PtBinaryExpression) {
if(address.operator=="+" && address.right.type==DataType.UWORD) {
if (address.left is PtIdentifier) {
// use (zp),Y instead of explicitly calculating the full zp pointer value
val pointer = (address.left as PtIdentifier).name
when(val index=address.right) {
is PtIdentifier -> {
val indexName = index.name
asmgen.out("""
lda $pointer
sta P8ZP_SCRATCH_W2
lda $pointer+1
clc
adc $indexName+1
sta P8ZP_SCRATCH_W2+1
ldy $indexName
lda (P8ZP_SCRATCH_W2),y""")
assignRegisterByte(target, CpuRegister.A, false, true)
return
}
is PtNumber -> {
val indexValue = index.number.toString()
asmgen.out("""
lda $pointer
sta P8ZP_SCRATCH_W2
lda $pointer+1
clc
adc #>$indexValue
sta P8ZP_SCRATCH_W2+1
ldy #<$indexValue
lda (P8ZP_SCRATCH_W2),y""")
assignRegisterByte(target, CpuRegister.A, false, true)
return
}
else -> {}
}
}
}
// else if(address.operator=="-") {
// // does this ever occur? we could optimize it too, but it seems like a pathological case
// }
}
assignExpressionToVariable(address, "P8ZP_SCRATCH_W2", DataType.UWORD)
asmgen.loadAFromZpPointerVar("P8ZP_SCRATCH_W2", false)
assignRegisterByte(target, CpuRegister.A, false, true)
}
private fun storeByteInAToAddressExpression(addressExpr: PtExpression, saveA: Boolean) {
// TODO optimize this into more efficient code, using indexed register ,Y instead of explicitly calculating the full pointer value, or use self=modifying code and just use absolute addressing.
// see: https://discord.com/channels/547559626024157184/629863245934755860/1262873088782110750
private fun storeByteInAToAddressExpression(address: PtExpression, saveA: Boolean) {
if(address is PtBinaryExpression) {
if(address.operator=="+") {
if (address.left is PtIdentifier && address.right.type==DataType.UWORD) {
// use (zp),Y instead of explicitly calculating the full zp pointer value
val pointer = (address.left as PtIdentifier).name
when(val index=address.right) {
is PtIdentifier -> {
val indexName = index.name
asmgen.out("""
tax
lda $pointer
sta P8ZP_SCRATCH_W2
lda $pointer+1
clc
adc $indexName+1
sta P8ZP_SCRATCH_W2+1
ldy $indexName
txa
sta (P8ZP_SCRATCH_W2),y""")
return
}
is PtNumber -> {
val indexValue = index.number.toString()
asmgen.out("""
tax
lda $pointer
sta P8ZP_SCRATCH_W2
lda $pointer+1
clc
adc #>$indexValue
sta P8ZP_SCRATCH_W2+1
ldy #<$indexValue
txa
sta (P8ZP_SCRATCH_W2),y""")
return
}
else -> {}
}
}
}
// else if(address.operator=="-") {
// // does this ever occur? we could optimize it too, but it seems like a pathological case
// }
}
if(saveA) asmgen.out(" pha")
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD)
assignExpressionToVariable(address, "P8ZP_SCRATCH_W2", DataType.UWORD)
if(saveA) asmgen.out(" pla")
asmgen.storeAIntoZpPointerVar("P8ZP_SCRATCH_W2", false)
}

View File

@ -3,7 +3,10 @@ TODO
See open issues on github.
Optimize code in assignByteFromAddressExpression() and storeByteInAToAddressExpression()
Generate proper index out of bounds error for array[-11] if the array is only size 10. (only array[-1]..array[-10] are valid)
Putting a signed variable as an array index should be a compiler error. (using it for a pointer indexing is fine - but weird).
Add some more explanation about this to the "array indexing" paragraph in the docs.
Re-generate the skeletons doc files.

View File

@ -8,10 +8,47 @@ main {
uword @shared ptr = $2000
uword @shared index = 1000
@($2000+1000) = 123
@($2000+1001) = 124
cx16.r0L = @(ptr+index)
cx16.r1L = ptr[index]
cx16.r1L = @(ptr+1001)
txt.print_ub(cx16.r0L)
txt.spc()
txt.print_ub(cx16.r1L)
txt.spc()
cx16.r2L = ptr[index]
cx16.r3L = ptr[1001]
txt.print_ub(cx16.r2L)
txt.spc()
txt.print_ub(cx16.r3L)
txt.spc()
cx16.r0L = 200
cx16.r1L = 201
@(ptr+index) = cx16.r0L
ptr[index] = cx16.r1L
@(ptr+1001) = cx16.r1L
txt.print_ub(@($2000+1000))
txt.spc()
txt.print_ub(@($2000+1001))
txt.spc()
cx16.r0L = 203
cx16.r1L = 204
ptr[index] = cx16.r0L
ptr[1001] = cx16.r1L
txt.print_ub(@($2000+1000))
txt.spc()
txt.print_ub(@($2000+1001))
txt.spc()
; txt.print_ub(ptr[index])
; txt.nl()
; ptr[index] = 123