diff --git a/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt index 584d54df3..62929674d 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt @@ -168,7 +168,7 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio throw AssemblyError("non-array var indexing requires bytes index") val idxReg = codeGen.vmRegisters.nextFree() code += expressionEval.translateExpression(array.index, idxReg, -1) - code += VmCodeInstruction(Opcode.LOADIX, vmDt, reg1=resultRegister, reg2=idxReg, value = variableAddr) + code += VmCodeInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, value = variableAddr) return code } diff --git a/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt index fae961ea5..45916146a 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt @@ -42,10 +42,10 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: "sort" -> funcSort(call) "reverse" -> funcReverse(call) "swap" -> funcSwap(call) - "rol" -> funcRolRor2(Opcode.ROXL, call, resultRegister) - "ror" -> funcRolRor2(Opcode.ROXR, call, resultRegister) - "rol2" -> funcRolRor2(Opcode.ROL, call, resultRegister) - "ror2" -> funcRolRor2(Opcode.ROR, call, resultRegister) + "rol" -> funcRolRor(Opcode.ROXL, call, resultRegister) + "ror" -> funcRolRor(Opcode.ROXR, call, resultRegister) + "rol2" -> funcRolRor(Opcode.ROL, call, resultRegister) + "ror2" -> funcRolRor(Opcode.ROR, call, resultRegister) else -> TODO("builtinfunc ${call.name}") } } @@ -368,7 +368,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: return code } - private fun funcRolRor2(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { + private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val vmDt = codeGen.vmType(call.args[0].type) val code = VmCodeChunk() code += exprGen.translateExpression(call.args[0], resultRegister, -1) diff --git a/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt b/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt index 26a3c82e7..b68b7df18 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstOnetimeTransforms.kt @@ -50,17 +50,14 @@ internal class AstOnetimeTransforms(private val program: Program, private val op } else { val fcall = parent as? IFunctionCall if(fcall!=null) { - // TODO for now, codegen seems wrong when using pointer indexed args to an in-place modifying function. - if(fcall.target.nameInSource.size==1 && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) { + // TODO currently, 6502 codegen is wrong when using pointer indexed args to an in-place modifying function. + if(options.compTarget.name!=VMTarget.NAME + && fcall.target.nameInSource.size==1 + && fcall.target.nameInSource[0] in InplaceModifyingBuiltinFunctions) { val memread = DirectMemoryRead(add, arrayIndexedExpression.position) return listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) - } else { - return noModifications } } - else { - return noModifications - } } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 01e9b1bec..8e81c0622 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- optimize pointervar indexing codegen: make them work as params to in-place modifying functions (rol, swap, ...) +- optimize pointervar indexing codegen: fix 6502 codegen for params to in-place modifying functions (rol, swap, ...) - optimize pointervar indexing codegen: writing (all sorts of things) - 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? diff --git a/examples/test.p8 b/examples/test.p8 index 47633b07a..c9f35843d 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -29,22 +29,6 @@ main { ; txt.spc() ; } -; sub derp(ubyte u1, ubyte u2, ubyte u3) { -; txt.print_ub(u1) -; txt.spc() -; txt.print_ub(u2) -; txt.spc() -; txt.print_ub(u3) -; txt.nl() -; } - - sub derp2(ubyte u1, ubyte u2) { - txt.print_ub(u1) - txt.spc() - txt.print_ub(u2) - txt.nl() - } - sub start() { ; mcCarthy() ;test_stack.test() @@ -55,66 +39,55 @@ main { ubyte[10] data = [11,22,33,4,5,6,7,8,9,10] uword bitmapbuf = &data - ;derp(data[0],data[1],data[2]) - ;derp(bitmapbuf[0], bitmapbuf[1], bitmapbuf[2]) - derp2(1,2) - derp2(one, two) - derp2(data[1], data[2]) - derp2(bitmapbuf[1], bitmapbuf[2]) + ; 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() -; value = bitmapbuf[2] -; txt.print_ub(value) ;; 33 -; txt.nl() -; -; ; 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() -; -; bitmapbuf[0] = one -; bitmapbuf[1] = one+one -; bitmapbuf[2] = one+one+one -; bitmapbuf[2] += 4 -; bitmapbuf[2] -= 2 -; bitmapbuf[2] -= 2 -; swap(bitmapbuf[0], bitmapbuf[1]) -; -; ; 2 1 3 -; txt.print_ub(bitmapbuf[0]) -; txt.spc() -; txt.print_ub(bitmapbuf[1]) -; txt.spc() -; txt.print_ub(bitmapbuf[2]) -; txt.nl() -; -; for value in data { -; txt.print_ub(value) -; txt.spc() -; } -; 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 + bitmapbuf[1] = one+one + bitmapbuf[2] = one+one+one + bitmapbuf[2] += 4 + bitmapbuf[2] -= 2 + bitmapbuf[2] -= 2 + swap(bitmapbuf[0], bitmapbuf[1]) + + ; 2 1 3 + txt.print_ub(bitmapbuf[0]) + txt.spc() + txt.print_ub(bitmapbuf[1]) + txt.spc() + txt.print_ub(bitmapbuf[2]) + txt.nl() + + for value in data { + txt.print_ub(value) + txt.spc() + } + txt.nl() ;test_stack.test() diff --git a/virtualmachine/src/prog8/vm/Instructions.kt b/virtualmachine/src/prog8/vm/Instructions.kt index ec6eb706d..6e4e637d9 100644 --- a/virtualmachine/src/prog8/vm/Instructions.kt +++ b/virtualmachine/src/prog8/vm/Instructions.kt @@ -31,6 +31,7 @@ loadr reg1, reg2 - load reg1 with value in register reg2 storem reg1, address - store reg1 at memory address storei reg1, reg2 - store reg1 at memory indirect, memory pointed to by reg2 storex reg1, reg2, address - store reg1 at memory address, indexed by value in reg2 +storeix reg1, reg2, pointeraddr - store reg1 at memory indirect, pointed to by pointeraddr indexed by value in reg2 storezm address - store zero at memory address storezi reg1 - store zero at memory pointed to by reg1 storezx reg1, address - store zero at memory address, indexed by value in reg @@ -190,6 +191,7 @@ enum class Opcode { STOREM, STOREI, STOREX, + STOREIX, STOREZM, STOREZI, STOREZX, @@ -489,7 +491,8 @@ val instructionFormats = mutableMapOf( Opcode.STOREM to InstructionFormat.from("BW,r1,v | F,fr1,v"), Opcode.STOREI to InstructionFormat.from("BW,r1,r2 | F,fr1,r1"), Opcode.STOREX to InstructionFormat.from("BW,r1,r2,v | F,fr1,r1,v"), - Opcode.STOREZM to InstructionFormat.from("BW,v | F,v"), + Opcode.STOREIX to InstructionFormat.from("BW,r1,r2,v | F,fr1,r1,v"), + Opcode.STOREZM to InstructionFormat.from("BW,v | F,v"), Opcode.STOREZI to InstructionFormat.from("BW,r1 | F,r1"), Opcode.STOREZX to InstructionFormat.from("BW,r1,v | F,r1,v"), Opcode.JUMP to InstructionFormat.from("N,v"), diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index 9815c01d3..08aa6d438 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -95,6 +95,7 @@ class VirtualMachine(val memory: Memory, program: List) { Opcode.LOADR -> InsLOADR(ins) Opcode.STOREM -> InsSTOREM(ins) Opcode.STOREX -> InsSTOREX(ins) + Opcode.STOREIX -> InsSTOREIX(ins) Opcode.STOREI -> InsSTOREI(ins) Opcode.STOREZM -> InsSTOREZM(ins) Opcode.STOREZX -> InsSTOREZX(ins) @@ -363,6 +364,24 @@ class VirtualMachine(val memory: Memory, program: List) { pc++ } + private fun InsSTOREIX(i: Instruction) { + when (i.type!!) { + VmDataType.BYTE -> { + val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!) + memory.setUB(pointer.toInt(), registers.getUB(i.reg1!!)) + } + VmDataType.WORD -> { + val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!) + memory.setUW(pointer.toInt(), registers.getUW(i.reg1!!)) + } + VmDataType.FLOAT -> { + val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg1!!) + memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!)) + } + } + pc++ + } + private fun InsSTOREZM(i: Instruction) { when(i.type!!) { VmDataType.BYTE -> memory.setUB(i.value!!, 0u)