mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +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 elementDt = assign.source.datatype
|
||||
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()
|
||||
if (constIndex!=null) {
|
||||
// constant array index value
|
||||
|
@ -149,6 +149,20 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
||||
val code = VmCodeChunk()
|
||||
val idxReg = codeGen.vmRegisters.nextFree()
|
||||
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) {
|
||||
// optimized code when index is known - just calculate the memory address here
|
||||
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) {
|
||||
val fname = fcall.target.nameInSource
|
||||
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)
|
||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||
} else {
|
||||
// TODO first candidate for optimization is to remove this:
|
||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
|
||||
noModifications
|
||||
}
|
||||
} else {
|
||||
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
|
||||
|
@ -1,5 +1,5 @@
|
||||
%import textio
|
||||
%zeropage dontuse
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||
|
Loading…
Reference in New Issue
Block a user