mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimized codegen for assigning value or variable to indexed pointer. (6502)
This commit is contained in:
parent
b042b7705e
commit
3075578245
@ -1384,6 +1384,22 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
storeRegisterAInMemoryAddress(target.memory!!)
|
storeRegisterAInMemoryAddress(target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
if(target.origAstTarget?.arrayindexed?.arrayvar?.targetVarDecl(program)?.datatype==DataType.UWORD) {
|
||||||
|
// assigning an indexed pointer var
|
||||||
|
if (target.constArrayIndexValue==0u) {
|
||||||
|
asmgen.out(" lda $sourceName")
|
||||||
|
asmgen.storeAIntoPointerVar(target.origAstTarget.arrayindexed!!.arrayvar)
|
||||||
|
} else {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||||
|
if (asmgen.isZpVar(target.origAstTarget.arrayindexed!!.arrayvar)) {
|
||||||
|
asmgen.out(" lda $sourceName | sta (${target.asmVarname}),y")
|
||||||
|
} else {
|
||||||
|
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
||||||
|
asmgen.out(" lda $sourceName | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt()
|
val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt()
|
||||||
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
|
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
|
||||||
@ -1916,6 +1932,22 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
storeRegisterAInMemoryAddress(target.memory!!)
|
storeRegisterAInMemoryAddress(target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
if(target.origAstTarget?.arrayindexed?.arrayvar?.targetVarDecl(program)?.datatype==DataType.UWORD) {
|
||||||
|
// assigning an indexed pointer var
|
||||||
|
if (target.constArrayIndexValue==0u) {
|
||||||
|
asmgen.out(" lda #0")
|
||||||
|
asmgen.storeAIntoPointerVar(target.origAstTarget.arrayindexed!!.arrayvar)
|
||||||
|
} else {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||||
|
if (asmgen.isZpVar(target.origAstTarget.arrayindexed!!.arrayvar)) {
|
||||||
|
asmgen.out(" lda #0 | sta (${target.asmVarname}),y")
|
||||||
|
} else {
|
||||||
|
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
||||||
|
asmgen.out(" lda #0 | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
val indexValue = target.constArrayIndexValue!!
|
val indexValue = target.constArrayIndexValue!!
|
||||||
asmgen.out(" stz ${target.asmVarname}+$indexValue")
|
asmgen.out(" stz ${target.asmVarname}+$indexValue")
|
||||||
@ -1959,13 +1991,29 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
storeRegisterAInMemoryAddress(target.memory!!)
|
storeRegisterAInMemoryAddress(target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
|
if(target.origAstTarget?.arrayindexed?.arrayvar?.targetVarDecl(program)?.datatype==DataType.UWORD) {
|
||||||
|
// assigning an indexed pointer var
|
||||||
|
if (target.constArrayIndexValue==0u) {
|
||||||
|
asmgen.out(" lda #${byte.toHex()}")
|
||||||
|
asmgen.storeAIntoPointerVar(target.origAstTarget.arrayindexed!!.arrayvar)
|
||||||
|
} else {
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||||
|
if (asmgen.isZpVar(target.origAstTarget.arrayindexed!!.arrayvar)) {
|
||||||
|
asmgen.out(" lda #${byte.toHex()} | sta (${target.asmVarname}),y")
|
||||||
|
} else {
|
||||||
|
asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1")
|
||||||
|
asmgen.out(" lda #${byte.toHex()} | sta (P8ZP_SCRATCH_W2),y")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
if (target.constArrayIndexValue!=null) {
|
if (target.constArrayIndexValue!=null) {
|
||||||
val indexValue = target.constArrayIndexValue!!
|
val indexValue = target.constArrayIndexValue!!
|
||||||
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname}+$indexValue")
|
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname}+$indexValue")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UBYTE, CpuRegister.Y)
|
||||||
asmgen.out(" lda #<${byte.toHex()} | sta ${target.asmVarname},y")
|
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname},y")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TargetStorageKind.REGISTER -> when(target.register!!) {
|
TargetStorageKind.REGISTER -> when(target.register!!) {
|
||||||
|
@ -2,10 +2,9 @@ package prog8.compiler.astprocessing
|
|||||||
|
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.expressions.ArrayIndexedExpression
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.expressions.BinaryExpression
|
|
||||||
import prog8.ast.expressions.Expression
|
|
||||||
import prog8.ast.statements.AssignTarget
|
import prog8.ast.statements.AssignTarget
|
||||||
|
import prog8.ast.statements.Assignment
|
||||||
import prog8.ast.statements.DirectMemoryWrite
|
import prog8.ast.statements.DirectMemoryWrite
|
||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
@ -31,13 +30,19 @@ internal class AstOnetimeTransforms(private val program: Program, private val op
|
|||||||
|
|
||||||
private fun replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
private fun replacePointerVarIndexWithMemreadOrMemwrite(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||||
if(options.compTarget.name== VMTarget.NAME)
|
if(options.compTarget.name== VMTarget.NAME)
|
||||||
return noModifications
|
return noModifications // vm codegen deals correctly with all cases
|
||||||
|
|
||||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||||
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
|
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
|
||||||
if(parent is AssignTarget) {
|
if(parent is AssignTarget) {
|
||||||
// rewrite assignment target pointervar[index] into @(pointervar+index)
|
val assignment = parent.parent as? Assignment
|
||||||
//println("REWRITE POINTER INDEXED: ${arrayVar.name}[${arrayIndexedExpression.indexer.indexExpr}] as assignment target at ${parent.position}") // TODO
|
if(assignment?.value is NumericLiteral || assignment?.value is IdentifierReference) {
|
||||||
|
// ONLY for a constant assignment, or direct variable assignment, the codegen contains correct optimized code.
|
||||||
|
return noModifications
|
||||||
|
}
|
||||||
|
// Other cases aren't covered correctly by the 6502 codegen, and there are a LOT of cases.
|
||||||
|
// So rewrite assignment target pointervar[index] into @(pointervar+index)
|
||||||
|
// (the 6502 codegen covers all cases correctly for a direct memory assignment).
|
||||||
val indexer = arrayIndexedExpression.indexer
|
val indexer = arrayIndexedExpression.indexer
|
||||||
val add: Expression =
|
val add: Expression =
|
||||||
if(indexer.indexExpr.constValue(program)?.number==0.0)
|
if(indexer.indexExpr.constValue(program)?.number==0.0)
|
||||||
|
@ -3,7 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- 6502: fix optimized pointervar indexing codegen when it is an assignment target (i.e. writing to ptr[ix])
|
|
||||||
- pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target.
|
- pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target.
|
||||||
- add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?
|
- add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value?
|
||||||
- Inliner: also inline function call expressions, and remove it from the StatementOptimizer
|
- Inliner: also inline function call expressions, and remove it from the StatementOptimizer
|
||||||
|
@ -40,32 +40,32 @@ main {
|
|||||||
uword bitmapbuf = &data
|
uword bitmapbuf = &data
|
||||||
|
|
||||||
; 11 22 33
|
; 11 22 33
|
||||||
; txt.print_ub(bitmapbuf[0])
|
txt.print_ub(bitmapbuf[0])
|
||||||
; txt.spc()
|
txt.spc()
|
||||||
; txt.print_ub(bitmapbuf[1])
|
txt.print_ub(bitmapbuf[1])
|
||||||
; txt.spc()
|
txt.spc()
|
||||||
; txt.print_ub(bitmapbuf[2])
|
txt.print_ub(bitmapbuf[2])
|
||||||
; txt.nl()
|
txt.nl()
|
||||||
; rol(bitmapbuf[0])
|
rol(bitmapbuf[0])
|
||||||
; rol(bitmapbuf[0])
|
rol(bitmapbuf[0])
|
||||||
; txt.print_ub(bitmapbuf[0]) ; 44
|
txt.print_ub(bitmapbuf[0]) ; 44
|
||||||
; txt.spc()
|
txt.spc()
|
||||||
; ror(bitmapbuf[0])
|
ror(bitmapbuf[0])
|
||||||
; ror(bitmapbuf[0])
|
ror(bitmapbuf[0])
|
||||||
; txt.print_ub(bitmapbuf[0]) ; 11
|
txt.print_ub(bitmapbuf[0]) ; 11
|
||||||
; txt.nl()
|
txt.nl()
|
||||||
;
|
|
||||||
; ; 22 44 66
|
; 22 44 66
|
||||||
; txt.print_ub(bitmapbuf[0]*2)
|
txt.print_ub(bitmapbuf[0]*2)
|
||||||
; txt.spc()
|
txt.spc()
|
||||||
; txt.print_ub(bitmapbuf[1]*2)
|
txt.print_ub(bitmapbuf[1]*2)
|
||||||
; txt.spc()
|
txt.spc()
|
||||||
; txt.print_ub(bitmapbuf[2]*2)
|
txt.print_ub(bitmapbuf[2]*2)
|
||||||
; txt.nl()
|
txt.nl()
|
||||||
;
|
|
||||||
; value = one+one+one+one+one
|
value = one+one+one+one+one
|
||||||
; txt.print_ub(value) ; 5
|
txt.print_ub(value) ; 5
|
||||||
; txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
bitmapbuf[0] = one+one+one
|
bitmapbuf[0] = one+one+one
|
||||||
bitmapbuf[0] = one+one+one
|
bitmapbuf[0] = one+one+one
|
||||||
@ -76,6 +76,7 @@ main {
|
|||||||
bitmapbuf[2] = one
|
bitmapbuf[2] = one
|
||||||
bitmapbuf[2] = one
|
bitmapbuf[2] = one
|
||||||
bitmapbuf[2] = one
|
bitmapbuf[2] = one
|
||||||
|
bitmapbuf[3] = 42
|
||||||
bitmapbuf[2] += 100
|
bitmapbuf[2] += 100
|
||||||
bitmapbuf[2] -= 1
|
bitmapbuf[2] -= 1
|
||||||
bitmapbuf[2] -= 1
|
bitmapbuf[2] -= 1
|
||||||
@ -91,7 +92,7 @@ main {
|
|||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
for value in data {
|
for value in data {
|
||||||
txt.print_ub(value) ; 3 2 97 4 5 6 7 8 9 10
|
txt.print_ub(value) ; 3 2 97 42 5 6 7 8 9 10
|
||||||
txt.spc()
|
txt.spc()
|
||||||
}
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
Loading…
Reference in New Issue
Block a user