diff --git a/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt index dceec1f78..8f3348492 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/AssignmentGen.kt @@ -57,8 +57,9 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio code // do nothing, mem=mem null assignment. else { // read and write a (i/o) memory location to itself. - code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1 =0, value = address) - code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=0, value = address) + val tempReg = codeGen.vmRegisters.nextFree() + code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address) + code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address) code } } diff --git a/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt index ca5d122fd..fae961ea5 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt @@ -138,43 +138,49 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, -1) - code += VmCodeInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=0) + val reg = codeGen.vmRegisters.nextFree() + code += exprGen.translateExpression(call.args.single(), reg, -1) + code += VmCodeInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=reg) return code } private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, -1) - code += VmCodeInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=0) + val reg = codeGen.vmRegisters.nextFree() + code += exprGen.translateExpression(call.args.single(), reg, -1) + code += VmCodeInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=reg) return code } private fun funcPop(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() - code += VmCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=0) - code += assignRegisterTo(call.args.single(), 0) + val reg = codeGen.vmRegisters.nextFree() + code += VmCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=reg) + code += assignRegisterTo(call.args.single(), reg) return code } private fun funcPopw(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() - code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1=0) - code += assignRegisterTo(call.args.single(), 0) + val reg = codeGen.vmRegisters.nextFree() + code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1=reg) + code += assignRegisterTo(call.args.single(), reg) return code } private fun funcPush(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, -1) - code += VmCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=0) + val reg = codeGen.vmRegisters.nextFree() + code += exprGen.translateExpression(call.args.single(), reg, -1) + code += VmCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=reg) return code } private fun funcPushw(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, -1) - code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1=0) + val reg = codeGen.vmRegisters.nextFree() + code += exprGen.translateExpression(call.args.single(), reg, -1) + code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1=reg) return code } diff --git a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt index a352ae38c..029a857e7 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt @@ -202,15 +202,16 @@ class CodeGen(internal val program: PtProgram, val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable val loopvarAddress = allocations.get(loopvar.scopedName) val indexReg = vmRegisters.nextFree() + val tmpReg = vmRegisters.nextFree() val loopLabel = createLabelName() val endLabel = createLabelName() if(iterableVar.dt==DataType.STR) { // iterate over a zero-terminated string code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) code += VmCodeLabel(loopLabel) - code += VmCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1 = 0, reg2=indexReg, value = arrayAddress) - code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=0, labelSymbol = endLabel) - code += VmCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=0, value = loopvarAddress) + code += VmCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, value = arrayAddress) + code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel) + code += VmCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, value = loopvarAddress) code += translateNode(forLoop.statements) code += VmCodeInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg) code += VmCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel) @@ -225,8 +226,8 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=lengthReg, value=lengthBytes) code += VmCodeLabel(loopLabel) code += VmCodeInstruction(Opcode.BEQ, VmDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = endLabel) - code += VmCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=0, reg2=indexReg, value=arrayAddress) - code += VmCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=0, value = loopvarAddress) + code += VmCodeInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, value=arrayAddress) + code += VmCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, value = loopvarAddress) code += translateNode(forLoop.statements) code += addConstReg(VmDataType.BYTE, indexReg, elementSize) code += VmCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel) @@ -288,7 +289,7 @@ class CodeGen(internal val program: PtProgram, endvalueReg = vmRegisters.nextFree() code += VmCodeInstruction(Opcode.LOAD, loopvarDt, reg1 = endvalueReg, value = rangeEndWrapped) } else { - endvalueReg = 0 + endvalueReg = -1 // not used } code += VmCodeInstruction(Opcode.LOAD, loopvarDt, reg1=indexReg, value=rangeStart) code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index f7ba6dee7..56aed5396 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,9 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- vm: don't use register 0/1 "as convenience" where it's not required, just allocate a new register anyway. - search for reg.\s?=\s?0 - ... diff --git a/examples/test.p8 b/examples/test.p8 index 84fa138ee..589ae3a07 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,53 +7,56 @@ ; NOTE: meant to test to virtual machine output target (use -target vitual) -other { - ubyte value = 42 - - sub getter() -> ubyte { - return value - } -} - main { - sub ands(ubyte arg, ubyte b1, ubyte b2, ubyte b3, ubyte b4) -> ubyte { - return arg>b1 and arg>b2 and arg>b3 and arg>b4 - } +; sub ands(ubyte arg, ubyte b1, ubyte b2, ubyte b3, ubyte b4) -> ubyte { +; return arg>b1 and arg>b2 and arg>b3 and arg>b4 +; } +; +; sub ors(ubyte arg, ubyte b1, ubyte b2, ubyte b3, ubyte b4) -> ubyte { +; return arg==b1 or arg==b2 or arg==b3 or arg==b4 +; } - sub ors(ubyte arg, ubyte b1, ubyte b2, ubyte b3, ubyte b4) -> ubyte { - return arg==b1 or arg==b2 or arg==b3 or arg==b4 - } +; sub mcCarthy() { +; ubyte @shared a +; ubyte @shared b +; +; txt.print_ub(ands(10, 2,3,4,5)) +; txt.spc() +; txt.print_ub(ands(10, 20,3,4,5)) +; txt.spc() +; txt.print_ub(ors(10, 2,3,40,5)) +; txt.spc() +; txt.print_ub(ors(10, 1,10,40,5)) +; txt.spc() +; } sub start() { - ubyte @shared a - ubyte @shared b + ; mcCarthy() - txt.print_ub(ands(10, 2,3,4,5)) - txt.spc() - txt.print_ub(ands(10, 20,3,4,5)) - txt.spc() - txt.print_ub(ors(10, 2,3,40,5)) - txt.spc() - txt.print_ub(ors(10, 1,10,40,5)) - txt.spc() + ubyte bb + for bb in 250 to 255 { + txt.print_ub(bb) + txt.spc() + } + txt.nl() ; ; a "pixelshader": -; sys.gfx_enable(0) ; enable lo res screen -; ubyte shifter -; -; repeat { -; uword xx -; uword yy = 0 -; repeat 240 { -; xx = 0 -; repeat 320 { -; sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) -; xx++ -; } -; yy++ -; } -; shifter+=4 -; } + sys.gfx_enable(0) ; enable lo res screen + ubyte shifter + + repeat { + uword xx + uword yy = 0 + repeat 240 { + xx = 0 + repeat 320 { + sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) + xx++ + } + yy++ + } + shifter+=4 + } } }