From 04df3c9f7f9473e0982f3f2da7b7ce777e4f32a3 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 17 Mar 2024 13:39:05 +0100 Subject: [PATCH] vm: implemented in-place array multiplication better --- .../codegen/intermediate/AssignmentGen.kt | 23 ++++++++++++++++++- compiler/test/TestCompilerOnExamples.kt | 2 +- examples/test.p8 | 22 ++++++++++-------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index 6b3562d19..92cf32e75 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -711,7 +711,24 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express private fun operatorMultiplyInplace(symbol: String?, array: PtArrayIndexer?, constAddress: Int?, memory: PtMemoryByte?, vmDt: IRDataType, operand: PtExpression): IRCodeChunks? { if(array!=null) { - TODO("* in array") + val eltSize = codeGen.program.memsizer.memorySize(array.type) + val result = mutableListOf() + if(array.splitWords) + return operatorMultiplyInplaceSplitArray(array, operand) + val eltDt = irType(array.type) + val constIndex = array.index.asConstInteger() + val constValue = operand.asConstInteger() + if(constIndex!=null && constValue!=null) { + if(constValue!=1) { + val valueReg=codeGen.registers.nextFree() + result += IRCodeChunk(null, null).also { + it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue) + it += IRInstruction(Opcode.MULM, eltDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize) + } + } + return result + } + return null // TODO("inplace array * non-const") } if(constAddress==null && memory!=null) return null // TODO("optimized memory in-place *"") @@ -813,6 +830,10 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express return result } + private fun operatorMultiplyInplaceSplitArray(array: PtArrayIndexer, operand: PtExpression): IRCodeChunks? { + return null // TODO("inplace split word array *") + } + private fun operatorMinusInplaceSplitArray(array: PtArrayIndexer, operand: PtExpression): IRCodeChunks? { val result = mutableListOf() val constIndex = array.index.asConstInteger() diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index e24db3025..5bdf9902c 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -208,7 +208,7 @@ class TestCompilerOnExamplesVirtual: FunSpec({ val (displayName, filepath) = prepareTestFiles(it, false, target) test(displayName) { val src = filepath.readText() - compileText(target, true, src, writeAssembly = true) shouldNotBe null + compileText(target, false, src, writeAssembly = true) shouldNotBe null compileText(target, true, src, writeAssembly = true) shouldNotBe null } } diff --git a/examples/test.p8 b/examples/test.p8 index cceb7b1b4..34c9f1da7 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,16 +3,20 @@ %option no_sysinit main { - ubyte tw = other.width() sub start() { - tw++ - txt.print_uw(tw) - } -} + ubyte[] ubarray = [11,22,33] + uword[] uwarray = [1111,2222,3333] + uword[] @split suwarray = [1111,2222,3333] + + ubarray[1] *= 10 + uwarray[1] *= 10 + suwarray[1] *= 10 -other { - sub width() -> ubyte { - cx16.r0++ - return 80 + txt.print_ub(ubarray[1]) + txt.nl() + txt.print_uw(uwarray[1]) + txt.nl() + txt.print_uw(suwarray[1]) + txt.nl() } }