vm: just use new register instead of trying to (ab)use reg 0

This commit is contained in:
Irmen de Jong 2022-05-22 23:38:46 +02:00
parent ba614801ee
commit 0a48ef3030
5 changed files with 71 additions and 63 deletions

View File

@ -57,8 +57,9 @@ internal class AssignmentGen(private val codeGen: CodeGen, private val expressio
code // do nothing, mem=mem null assignment. code // do nothing, mem=mem null assignment.
else { else {
// read and write a (i/o) memory location to itself. // read and write a (i/o) memory location to itself.
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1 =0, value = address) val tempReg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=0, value = address) code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address)
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address)
code code
} }
} }

View File

@ -138,43 +138,49 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += exprGen.translateExpression(call.args.single(), 0, -1) val reg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=0) code += exprGen.translateExpression(call.args.single(), reg, -1)
code += VmCodeInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=reg)
return code return code
} }
private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += exprGen.translateExpression(call.args.single(), 0, -1) val reg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=0) code += exprGen.translateExpression(call.args.single(), reg, -1)
code += VmCodeInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=reg)
return code return code
} }
private fun funcPop(call: PtBuiltinFunctionCall): VmCodeChunk { private fun funcPop(call: PtBuiltinFunctionCall): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += VmCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=0) val reg = codeGen.vmRegisters.nextFree()
code += assignRegisterTo(call.args.single(), 0) code += VmCodeInstruction(Opcode.POP, VmDataType.BYTE, reg1=reg)
code += assignRegisterTo(call.args.single(), reg)
return code return code
} }
private fun funcPopw(call: PtBuiltinFunctionCall): VmCodeChunk { private fun funcPopw(call: PtBuiltinFunctionCall): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1=0) val reg = codeGen.vmRegisters.nextFree()
code += assignRegisterTo(call.args.single(), 0) code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1=reg)
code += assignRegisterTo(call.args.single(), reg)
return code return code
} }
private fun funcPush(call: PtBuiltinFunctionCall): VmCodeChunk { private fun funcPush(call: PtBuiltinFunctionCall): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += exprGen.translateExpression(call.args.single(), 0, -1) val reg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=0) code += exprGen.translateExpression(call.args.single(), reg, -1)
code += VmCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=reg)
return code return code
} }
private fun funcPushw(call: PtBuiltinFunctionCall): VmCodeChunk { private fun funcPushw(call: PtBuiltinFunctionCall): VmCodeChunk {
val code = VmCodeChunk() val code = VmCodeChunk()
code += exprGen.translateExpression(call.args.single(), 0, -1) val reg = codeGen.vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1=0) code += exprGen.translateExpression(call.args.single(), reg, -1)
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1=reg)
return code return code
} }

View File

@ -202,15 +202,16 @@ class CodeGen(internal val program: PtProgram,
val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable
val loopvarAddress = allocations.get(loopvar.scopedName) val loopvarAddress = allocations.get(loopvar.scopedName)
val indexReg = vmRegisters.nextFree() val indexReg = vmRegisters.nextFree()
val tmpReg = vmRegisters.nextFree()
val loopLabel = createLabelName() val loopLabel = createLabelName()
val endLabel = createLabelName() val endLabel = createLabelName()
if(iterableVar.dt==DataType.STR) { if(iterableVar.dt==DataType.STR) {
// iterate over a zero-terminated string // iterate over a zero-terminated string
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0)
code += VmCodeLabel(loopLabel) code += VmCodeLabel(loopLabel)
code += VmCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1 = 0, reg2=indexReg, value = arrayAddress) code += VmCodeInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, value = arrayAddress)
code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=0, labelSymbol = endLabel) code += VmCodeInstruction(Opcode.BZ, VmDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel)
code += VmCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=0, value = loopvarAddress) code += VmCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, value = loopvarAddress)
code += translateNode(forLoop.statements) code += translateNode(forLoop.statements)
code += VmCodeInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg) code += VmCodeInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg)
code += VmCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel) 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 += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=lengthReg, value=lengthBytes)
code += VmCodeLabel(loopLabel) code += VmCodeLabel(loopLabel)
code += VmCodeInstruction(Opcode.BEQ, VmDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = endLabel) 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.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, value=arrayAddress)
code += VmCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=0, value = loopvarAddress) code += VmCodeInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, value = loopvarAddress)
code += translateNode(forLoop.statements) code += translateNode(forLoop.statements)
code += addConstReg(VmDataType.BYTE, indexReg, elementSize) code += addConstReg(VmDataType.BYTE, indexReg, elementSize)
code += VmCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel) code += VmCodeInstruction(Opcode.JUMP, labelSymbol = loopLabel)
@ -288,7 +289,7 @@ class CodeGen(internal val program: PtProgram,
endvalueReg = vmRegisters.nextFree() endvalueReg = vmRegisters.nextFree()
code += VmCodeInstruction(Opcode.LOAD, loopvarDt, reg1 = endvalueReg, value = rangeEndWrapped) code += VmCodeInstruction(Opcode.LOAD, loopvarDt, reg1 = endvalueReg, value = rangeEndWrapped)
} else { } else {
endvalueReg = 0 endvalueReg = -1 // not used
} }
code += VmCodeInstruction(Opcode.LOAD, loopvarDt, reg1=indexReg, value=rangeStart) code += VmCodeInstruction(Opcode.LOAD, loopvarDt, reg1=indexReg, value=rangeStart)
code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress) code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress)

View File

@ -3,9 +3,6 @@ TODO
For next release 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
... ...

View File

@ -7,53 +7,56 @@
; NOTE: meant to test to virtual machine output target (use -target vitual) ; NOTE: meant to test to virtual machine output target (use -target vitual)
other {
ubyte value = 42
sub getter() -> ubyte {
return value
}
}
main { main {
sub ands(ubyte arg, ubyte b1, ubyte b2, ubyte b3, ubyte b4) -> ubyte { ; 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 ; 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 { ; sub mcCarthy() {
return arg==b1 or arg==b2 or arg==b3 or arg==b4 ; 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() { sub start() {
ubyte @shared a ; mcCarthy()
ubyte @shared b
txt.print_ub(ands(10, 2,3,4,5)) ubyte bb
txt.spc() for bb in 250 to 255 {
txt.print_ub(ands(10, 20,3,4,5)) txt.print_ub(bb)
txt.spc() txt.spc()
txt.print_ub(ors(10, 2,3,40,5)) }
txt.spc() txt.nl()
txt.print_ub(ors(10, 1,10,40,5))
txt.spc()
; ; a "pixelshader": ; ; a "pixelshader":
; sys.gfx_enable(0) ; enable lo res screen sys.gfx_enable(0) ; enable lo res screen
; ubyte shifter ubyte shifter
;
; repeat { repeat {
; uword xx uword xx
; uword yy = 0 uword yy = 0
; repeat 240 { repeat 240 {
; xx = 0 xx = 0
; repeat 320 { repeat 320 {
; sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte)
; xx++ xx++
; } }
; yy++ yy++
; } }
; shifter+=4 shifter+=4
; } }
} }
} }