mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +00:00
vm: just use new register instead of trying to (ab)use reg 0
This commit is contained in:
parent
ba614801ee
commit
0a48ef3030
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
; }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user