mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
improved codegen for some pointer+index expressions
This commit is contained in:
parent
9046fe8d3a
commit
d18f2a7bfd
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user