mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +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!!)
|
||||
}
|
||||
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) {
|
||||
val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt()
|
||||
asmgen.out(" lda $sourceName | sta ${target.asmVarname}+$scaledIdx")
|
||||
@ -1916,6 +1932,22 @@ internal class AssignmentAsmGen(private val program: Program,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
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) {
|
||||
val indexValue = target.constArrayIndexValue!!
|
||||
asmgen.out(" stz ${target.asmVarname}+$indexValue")
|
||||
@ -1959,13 +1991,29 @@ internal class AssignmentAsmGen(private val program: Program,
|
||||
storeRegisterAInMemoryAddress(target.memory!!)
|
||||
}
|
||||
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) {
|
||||
val indexValue = target.constArrayIndexValue!!
|
||||
asmgen.out(" lda #${byte.toHex()} | sta ${target.asmVarname}+$indexValue")
|
||||
}
|
||||
else {
|
||||
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!!) {
|
||||
|
@ -2,10 +2,9 @@ package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.expressions.ArrayIndexedExpression
|
||||
import prog8.ast.expressions.BinaryExpression
|
||||
import prog8.ast.expressions.Expression
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.AssignTarget
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.DirectMemoryWrite
|
||||
import prog8.ast.statements.VarDecl
|
||||
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> {
|
||||
if(options.compTarget.name== VMTarget.NAME)
|
||||
return noModifications
|
||||
return noModifications // vm codegen deals correctly with all cases
|
||||
|
||||
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
|
||||
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
|
||||
if(parent is AssignTarget) {
|
||||
// rewrite assignment target pointervar[index] into @(pointervar+index)
|
||||
//println("REWRITE POINTER INDEXED: ${arrayVar.name}[${arrayIndexedExpression.indexer.indexExpr}] as assignment target at ${parent.position}") // TODO
|
||||
val assignment = parent.parent as? Assignment
|
||||
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 add: Expression =
|
||||
if(indexer.indexExpr.constValue(program)?.number==0.0)
|
||||
|
@ -3,7 +3,6 @@ TODO
|
||||
|
||||
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.
|
||||
- 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
|
||||
|
@ -40,32 +40,32 @@ main {
|
||||
uword bitmapbuf = &data
|
||||
|
||||
; 11 22 33
|
||||
; txt.print_ub(bitmapbuf[0])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1])
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2])
|
||||
; txt.nl()
|
||||
; rol(bitmapbuf[0])
|
||||
; rol(bitmapbuf[0])
|
||||
; txt.print_ub(bitmapbuf[0]) ; 44
|
||||
; txt.spc()
|
||||
; ror(bitmapbuf[0])
|
||||
; ror(bitmapbuf[0])
|
||||
; txt.print_ub(bitmapbuf[0]) ; 11
|
||||
; txt.nl()
|
||||
;
|
||||
; ; 22 44 66
|
||||
; txt.print_ub(bitmapbuf[0]*2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[1]*2)
|
||||
; txt.spc()
|
||||
; txt.print_ub(bitmapbuf[2]*2)
|
||||
; txt.nl()
|
||||
;
|
||||
; value = one+one+one+one+one
|
||||
; txt.print_ub(value) ; 5
|
||||
; txt.nl()
|
||||
txt.print_ub(bitmapbuf[0])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[1])
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[2])
|
||||
txt.nl()
|
||||
rol(bitmapbuf[0])
|
||||
rol(bitmapbuf[0])
|
||||
txt.print_ub(bitmapbuf[0]) ; 44
|
||||
txt.spc()
|
||||
ror(bitmapbuf[0])
|
||||
ror(bitmapbuf[0])
|
||||
txt.print_ub(bitmapbuf[0]) ; 11
|
||||
txt.nl()
|
||||
|
||||
; 22 44 66
|
||||
txt.print_ub(bitmapbuf[0]*2)
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[1]*2)
|
||||
txt.spc()
|
||||
txt.print_ub(bitmapbuf[2]*2)
|
||||
txt.nl()
|
||||
|
||||
value = one+one+one+one+one
|
||||
txt.print_ub(value) ; 5
|
||||
txt.nl()
|
||||
|
||||
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[3] = 42
|
||||
bitmapbuf[2] += 100
|
||||
bitmapbuf[2] -= 1
|
||||
bitmapbuf[2] -= 1
|
||||
@ -91,7 +92,7 @@ main {
|
||||
txt.nl()
|
||||
|
||||
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.nl()
|
||||
|
Loading…
Reference in New Issue
Block a user