mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
optimized codegen for pointer indexing (read expressions)
This commit is contained in:
parent
7f69517fd4
commit
2002412026
@ -72,6 +72,23 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
val value = assign.source.array!!
|
val value = assign.source.array!!
|
||||||
val elementDt = assign.source.datatype
|
val elementDt = assign.source.datatype
|
||||||
val arrayVarName = asmgen.asmVariableName(value.arrayvar)
|
val arrayVarName = asmgen.asmVariableName(value.arrayvar)
|
||||||
|
|
||||||
|
val arrayVarDecl = value.arrayvar.targetVarDecl(program)!!
|
||||||
|
if(arrayVarDecl.datatype==DataType.UWORD) {
|
||||||
|
// indexing a pointer var instead of a real array or string
|
||||||
|
if(elementDt !in ByteDatatypes)
|
||||||
|
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||||
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
|
if(asmgen.isZpVar(value.arrayvar)) {
|
||||||
|
asmgen.out(" lda ($arrayVarName),y")
|
||||||
|
} else {
|
||||||
|
asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1")
|
||||||
|
asmgen.out(" lda (P8ZP_SCRATCH_W1),y")
|
||||||
|
}
|
||||||
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val constIndex = value.indexer.constIndex()
|
val constIndex = value.indexer.constIndex()
|
||||||
if (constIndex!=null) {
|
if (constIndex!=null) {
|
||||||
// constant array index value
|
// constant array index value
|
||||||
|
@ -149,6 +149,20 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
val idxReg = codeGen.vmRegisters.nextFree()
|
val idxReg = codeGen.vmRegisters.nextFree()
|
||||||
val arrayLocation = codeGen.allocations.get(arrayIx.variable.targetName)
|
val arrayLocation = codeGen.allocations.get(arrayIx.variable.targetName)
|
||||||
|
|
||||||
|
if(arrayIx.variable.type==DataType.UWORD) {
|
||||||
|
// indexing a pointer var instead of a real array or string
|
||||||
|
if(eltSize!=1)
|
||||||
|
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||||
|
val pointerReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += translateExpression(arrayIx.index, idxReg, -1)
|
||||||
|
// TODO introduce LOADIX instruction to skip the ADD (requires 3 registers)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADM, VmDataType.WORD, reg1=pointerReg, value=arrayLocation)
|
||||||
|
code += VmCodeInstruction(Opcode.ADD, VmDataType.WORD, reg1=pointerReg, reg2=idxReg)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1=resultRegister, reg2=pointerReg)
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
if(arrayIx.index is PtNumber) {
|
if(arrayIx.index is PtNumber) {
|
||||||
// optimized code when index is known - just calculate the memory address here
|
// optimized code when index is known - just calculate the memory address here
|
||||||
val memOffset = (arrayIx.index as PtNumber).number.toInt() * eltSize
|
val memOffset = (arrayIx.index as PtNumber).number.toInt() * eltSize
|
||||||
|
@ -45,13 +45,11 @@ internal class AstOnetimeTransforms(private val program: Program) : AstWalker()
|
|||||||
return if(fcall!=null) {
|
return if(fcall!=null) {
|
||||||
val fname = fcall.target.nameInSource
|
val fname = fcall.target.nameInSource
|
||||||
if(fname.size==1 && fname[0] in InplaceModifyingBuiltinFunctions) {
|
if(fname.size==1 && fname[0] in InplaceModifyingBuiltinFunctions) {
|
||||||
// TODO for now, swap() etc don't work on pointer var indexed args
|
// TODO for now, swap() etc don't work on pointer var indexed args, so still replace this
|
||||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||||
} else {
|
} else {
|
||||||
// TODO first candidate for optimization is to remove this:
|
noModifications
|
||||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
|
||||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage dontuse
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
|
||||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||||
|
Loading…
Reference in New Issue
Block a user