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.
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
}
}

View File

@ -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
}

View File

@ -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)

View File

@ -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
...

View File

@ -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
}
}
}