mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +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.
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user