From dc6475c91b7444c8254c2dbc7690bb6adec20742 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 17 May 2022 18:53:18 +0200 Subject: [PATCH] vm: fixed non-byte array indexing --- .../src/prog8/codegen/virtual/CodeGen.kt | 20 +++++- docs/source/todo.rst | 1 - examples/animals.p8 | 15 ++--- examples/test.p8 | 66 ++++++------------- 4 files changed, 45 insertions(+), 57 deletions(-) diff --git a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt index 64ff0ebb7..fbc186c92 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt @@ -701,7 +701,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.STOREZM, VmDataType.FLOAT, value=variableAddr) } else { val indexReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(array.index, indexReg, -1) + code += loadIndexReg(array, itemsize, indexReg) code += VmCodeInstruction(Opcode.STOREZX, VmDataType.FLOAT, reg1=indexReg, value=variableAddr) } } else { @@ -711,7 +711,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, value=variableAddr) } else { val indexReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(array.index, indexReg, -1) + code += loadIndexReg(array, itemsize, indexReg) code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, value=variableAddr) } } else { @@ -720,7 +720,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, value=variableAddr) } else { val indexReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(array.index, indexReg, -1) + code += loadIndexReg(array, itemsize, indexReg) code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, value=variableAddr) } } @@ -751,6 +751,20 @@ class CodeGen(internal val program: PtProgram, return code } + private fun loadIndexReg(array: PtArrayIndexer, itemsize: Int, indexReg: Int): VmCodeChunk { + val code = VmCodeChunk() + if(itemsize==1) { + code += expressionEval.translateExpression(array.index, indexReg, -1) + } + else { + val mult = PtBinaryExpression("*", DataType.UBYTE, array.position) + mult.children += array.index + mult.children += PtNumber(DataType.UBYTE, itemsize.toDouble(), array.position) + code += expressionEval.translateExpression(mult, indexReg, -1) + } + return code + } + private fun translate(ret: PtReturn): VmCodeChunk { val code = VmCodeChunk() val value = ret.value diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 8e48af706..83cf09df7 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- vm: animals example game breaks after adding first new animal... - vm: add more instructions operating directly on memory instead of only registers? (translate assignment self-assigns) - complete the Inliner - add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value? diff --git a/examples/animals.p8 b/examples/animals.p8 index 3c0016b94..7fea05a1c 100644 --- a/examples/animals.p8 +++ b/examples/animals.p8 @@ -4,19 +4,19 @@ ; Animal guessing game where the computer gets smarter every time. ; Note: this program is compatible with C64 and CX16. - main { const ubyte database_size = 100 - uword animal_names_buf = memory("animalnames", 500, 0) - uword questions_buf = memory("questions", 2000, 0) + uword animal_names_buf = memory("animalnames", 500, 0) ; area to store all animal names in, in sequence + uword questions_buf = memory("questions", 2000, 0) ; area to store all question texts in, in sequence uword animal_names_ptr uword questions_ptr - uword[database_size] animals - uword[database_size] questions - uword[database_size] answers_questions - uword[database_size] answers_animals + uword[database_size] animals ; pointers to the animal names + uword[database_size] questions ; pointers to the question texts + uword[database_size] answers_questions ; tree entries for question choices, indexed by question id, pair of (msb=yes, lsb=no) follow up question id (or 0 if it's an animal leaf node) + uword[database_size] answers_animals ; tree entries for animal leafs, indexed by question id, pair of (msb=yes, lsb=no) animal id + ubyte new_animal_number ubyte new_question_number str userinput = "x"*80 @@ -137,6 +137,5 @@ main { new_question_number++ txt.print("\n\nthanks, i know more animals now! let's try again.\n") - } } diff --git a/examples/test.p8 b/examples/test.p8 index 18faab313..3e2bef086 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -22,57 +22,33 @@ main { return first * second } + ubyte ix + sub start() { - ubyte @shared value = inline_candidate() + uword[] array = [1111,2222,3333,4444] - str name = "irmen123ABC" - str other = "zrmen123zzz" + sub pa() { + uword ww + for ww in array { + txt.print_uw(ww) + txt.spc() + } + txt.nl() + } - txt.print(name) - txt.nl() - uword otherptr = &other + 2 - name = otherptr - - txt.print(name) - txt.nl() - txt.nl() - - txt.print_ub(string.upper(name)) - txt.print(name) - txt.nl() - txt.print_ub(string.lower(name)) - txt.print(name) - txt.nl() - - uword otheraddr = &other - txt.print_ub(name!=other) - txt.spc() - txt.print_ub(name==other) - txt.nl() - txt.print_ub(name>other) - txt.spc() - txt.print_ub(name>=other) - txt.nl() - txt.print_ub(nameother) - txt.spc() - txt.print_ub(name>=other) - txt.nl() - txt.print_ub(name