mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
vm: use memory load instruction better
This commit is contained in:
parent
ec6ac5bf24
commit
a2c7273801
@ -18,11 +18,11 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
"msb" -> funcMsb(call, resultRegister)
|
"msb" -> funcMsb(call, resultRegister)
|
||||||
"lsb" -> funcLsb(call, resultRegister)
|
"lsb" -> funcLsb(call, resultRegister)
|
||||||
"memory" -> funcMemory(call, resultRegister)
|
"memory" -> funcMemory(call, resultRegister)
|
||||||
"rnd" -> funcRnd(call, resultRegister)
|
"rnd" -> funcRnd(resultRegister)
|
||||||
"peek" -> funcPeek(call, resultRegister)
|
"peek" -> funcPeek(call, resultRegister)
|
||||||
"peekw" -> funcPeekW(call, resultRegister)
|
"peekw" -> funcPeekW(call, resultRegister)
|
||||||
"poke" -> funcPoke(call, resultRegister)
|
"poke" -> funcPoke(call)
|
||||||
"pokew" -> funcPokeW(call, resultRegister)
|
"pokew" -> funcPokeW(call)
|
||||||
"pokemon" -> VmCodeChunk()
|
"pokemon" -> VmCodeChunk()
|
||||||
"mkword" -> funcMkword(call, resultRegister)
|
"mkword" -> funcMkword(call, resultRegister)
|
||||||
"sin8u" -> funcSin8u(call, resultRegister)
|
"sin8u" -> funcSin8u(call, resultRegister)
|
||||||
@ -136,47 +136,65 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcPokeW(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcPokeW(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||||
val addressReg = codeGen.vmRegisters.nextFree()
|
|
||||||
val valueReg = codeGen.vmRegisters.nextFree()
|
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += exprGen.translateExpression(call.args[0], addressReg)
|
val valueReg = codeGen.vmRegisters.nextFree()
|
||||||
code += exprGen.translateExpression(call.args[1], valueReg)
|
if(call.args[0] is PtNumber) {
|
||||||
// TODO use STOREM if constant address
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
code += VmCodeInstruction(Opcode.STOREI, VmDataType.WORD, reg1 = valueReg, reg2=addressReg)
|
code += exprGen.translateExpression(call.args[1], valueReg)
|
||||||
|
code += VmCodeInstruction(Opcode.STOREM, VmDataType.WORD, reg1 = valueReg, value=address)
|
||||||
|
} else {
|
||||||
|
val addressReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += exprGen.translateExpression(call.args[0], addressReg)
|
||||||
|
code += exprGen.translateExpression(call.args[1], valueReg)
|
||||||
|
code += VmCodeInstruction(Opcode.STOREI, VmDataType.WORD, reg1 = valueReg, reg2 = addressReg)
|
||||||
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcPoke(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcPoke(call: PtBuiltinFunctionCall): VmCodeChunk {
|
||||||
val addressReg = codeGen.vmRegisters.nextFree()
|
|
||||||
val valueReg = codeGen.vmRegisters.nextFree()
|
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += exprGen.translateExpression(call.args[0], addressReg)
|
val valueReg = codeGen.vmRegisters.nextFree()
|
||||||
code += exprGen.translateExpression(call.args[1], valueReg)
|
if(call.args[0] is PtNumber) {
|
||||||
// TODO use STOREM if constant address
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
code += VmCodeInstruction(Opcode.STOREI, VmDataType.BYTE, reg1 = valueReg, reg2=addressReg)
|
code += exprGen.translateExpression(call.args[1], valueReg)
|
||||||
|
code += VmCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1 = valueReg, value=address)
|
||||||
|
} else {
|
||||||
|
val addressReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += exprGen.translateExpression(call.args[0], addressReg)
|
||||||
|
code += exprGen.translateExpression(call.args[1], valueReg)
|
||||||
|
code += VmCodeInstruction(Opcode.STOREI, VmDataType.BYTE, reg1 = valueReg, reg2 = addressReg)
|
||||||
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcPeekW(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcPeekW(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
val addressReg = codeGen.vmRegisters.nextFree()
|
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += exprGen.translateExpression(call.args.single(), addressReg)
|
if(call.args[0] is PtNumber) {
|
||||||
// TODO use LOADM if constant address
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
code += VmCodeInstruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2=addressReg)
|
code += VmCodeInstruction(Opcode.LOADM, VmDataType.WORD, reg1 = resultRegister, value = address)
|
||||||
|
} else {
|
||||||
|
val addressReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += exprGen.translateExpression(call.args.single(), addressReg)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
|
||||||
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcPeek(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcPeek(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
val addressReg = codeGen.vmRegisters.nextFree()
|
if(call.args[0] is PtNumber) {
|
||||||
code += exprGen.translateExpression(call.args.single(), addressReg)
|
val address = (call.args[0] as PtNumber).number.toInt()
|
||||||
// TODO use LOADM if constant address
|
code += VmCodeInstruction(Opcode.LOADM, VmDataType.BYTE, reg1 = resultRegister, value = address)
|
||||||
code += VmCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1 = resultRegister, reg2=addressReg)
|
} else {
|
||||||
|
val addressReg = codeGen.vmRegisters.nextFree()
|
||||||
|
code += exprGen.translateExpression(call.args.single(), addressReg)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
|
||||||
|
}
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcRnd(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcRnd(resultRegister: Int): VmCodeChunk {
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += VmCodeInstruction(Opcode.SYSCALL, value= Syscall.RND.ordinal)
|
code += VmCodeInstruction(Opcode.SYSCALL, value= Syscall.RND.ordinal)
|
||||||
if(resultRegister!=0)
|
if(resultRegister!=0)
|
||||||
@ -203,7 +221,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun funcLsb(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcLsb(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
// TODO optimized code gen
|
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += exprGen.translateExpression(call.args.single(), resultRegister)
|
code += exprGen.translateExpression(call.args.single(), resultRegister)
|
||||||
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
|
||||||
@ -211,7 +228,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
// TODO optimized code gen
|
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
code += exprGen.translateExpression(call.args.single(), resultRegister)
|
code += exprGen.translateExpression(call.args.single(), resultRegister)
|
||||||
code += VmCodeInstruction(Opcode.MSIG, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister)
|
code += VmCodeInstruction(Opcode.MSIG, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister)
|
||||||
|
@ -459,12 +459,18 @@ class CodeGen(internal val program: PtProgram,
|
|||||||
code += VmCodeInstruction(operation, vmDt, reg1=resultReg)
|
code += VmCodeInstruction(operation, vmDt, reg1=resultReg)
|
||||||
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultReg, value = address)
|
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultReg, value = address)
|
||||||
} else if(memory!=null) {
|
} else if(memory!=null) {
|
||||||
val addressReg = vmRegisters.nextFree()
|
if(memory.address is PtNumber) {
|
||||||
code += expressionEval.translateExpression(memory.address, addressReg)
|
val address = (memory.address as PtNumber).number.toInt()
|
||||||
// TODO use LOADM/STOREM if address is constant
|
code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultReg, value = address)
|
||||||
code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1=resultReg, reg2=addressReg)
|
code += VmCodeInstruction(operation, vmDt, reg1 = resultReg)
|
||||||
code += VmCodeInstruction(operation, vmDt, reg1=resultReg)
|
code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, value=address)
|
||||||
code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1=resultReg, reg2=addressReg)
|
} else {
|
||||||
|
val addressReg = vmRegisters.nextFree()
|
||||||
|
code += expressionEval.translateExpression(memory.address, addressReg)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1 = resultReg, reg2 = addressReg)
|
||||||
|
code += VmCodeInstruction(operation, vmDt, reg1 = resultReg)
|
||||||
|
code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1 = resultReg, reg2 = addressReg)
|
||||||
|
}
|
||||||
} else if (array!=null) {
|
} else if (array!=null) {
|
||||||
val variable = array.variable.targetName
|
val variable = array.variable.targetName
|
||||||
var variableAddr = allocations.get(variable)
|
var variableAddr = allocations.get(variable)
|
||||||
|
@ -44,10 +44,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) {
|
|||||||
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=mem)
|
code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=mem)
|
||||||
}
|
}
|
||||||
is PtMemoryByte -> {
|
is PtMemoryByte -> {
|
||||||
val addressRegister = codeGen.vmRegisters.nextFree()
|
if(expr.address is PtNumber) {
|
||||||
code += translateExpression(expr.address, addressRegister)
|
val address = (expr.address as PtNumber).number.toInt()
|
||||||
// TODO use LOADM if adress is constant
|
code += VmCodeInstruction(Opcode.LOADM, VmDataType.BYTE, reg1=resultRegister, value = address)
|
||||||
code += VmCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1=resultRegister, reg2=addressRegister)
|
} else {
|
||||||
|
val addressRegister = codeGen.vmRegisters.nextFree()
|
||||||
|
code += translateExpression(expr.address, addressRegister)
|
||||||
|
code += VmCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1=resultRegister, reg2=addressRegister)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
is PtTypeCast -> code += translate(expr, resultRegister)
|
is PtTypeCast -> code += translate(expr, resultRegister)
|
||||||
is PtPrefix -> code += translate(expr, resultRegister)
|
is PtPrefix -> code += translate(expr, resultRegister)
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
; Written by Irmen de Jong (irmen@razorvine.net) - license: GNU GPL 3.0
|
||||||
|
|
||||||
math {
|
math {
|
||||||
; TODO
|
; required by the compiler, but the vm implements all math operations as instructions.
|
||||||
}
|
}
|
||||||
|
@ -7,45 +7,52 @@
|
|||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
|
|
||||||
uword other = $fe4a
|
pokew($1000, $ea31)
|
||||||
uword value = $ea31
|
poke($1001, $44)
|
||||||
uword[] warray = [$aa44, $bb55, $cc66]
|
txt.print_uwhex(peekw($1000), true)
|
||||||
ubyte upperb = msb(value)
|
|
||||||
ubyte lowerb = lsb(value)
|
|
||||||
txt.print_ubhex(upperb, true)
|
|
||||||
txt.print_ubhex(lowerb, false)
|
|
||||||
txt.nl()
|
|
||||||
value = mkword(upperb, lowerb)
|
|
||||||
txt.print_uwhex(value, true)
|
|
||||||
txt.nl()
|
|
||||||
upperb = msb(warray[1])
|
|
||||||
lowerb = lsb(warray[1])
|
|
||||||
txt.print_ubhex(upperb, true)
|
|
||||||
txt.print_ubhex(lowerb, false)
|
|
||||||
txt.nl()
|
|
||||||
ubyte index=1
|
|
||||||
upperb = msb(warray[index])
|
|
||||||
lowerb = lsb(warray[index])
|
|
||||||
txt.print_ubhex(upperb, true)
|
|
||||||
txt.print_ubhex(lowerb, false)
|
|
||||||
txt.nl()
|
|
||||||
swap(other, value)
|
|
||||||
txt.print_uwhex(value,true)
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
txt.print_ubhex(peek($1001), true)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
pokew($1000, $ab98)
|
; uword other = $fe4a
|
||||||
txt.print_ubhex(@($1000),true)
|
; uword value = $ea31
|
||||||
txt.print_ubhex(@($1001),false)
|
; uword[] warray = [$aa44, $bb55, $cc66]
|
||||||
txt.nl()
|
; ubyte upperb = msb(value)
|
||||||
txt.print_uwhex(peekw($1000),true)
|
; ubyte lowerb = lsb(value)
|
||||||
txt.nl()
|
; txt.print_ubhex(upperb, true)
|
||||||
swap(@($1000), @($1001))
|
; txt.print_ubhex(lowerb, false)
|
||||||
txt.print_uwhex(peekw($1000),true)
|
; txt.nl()
|
||||||
txt.nl()
|
; value = mkword(upperb, lowerb)
|
||||||
swap(warray[0], warray[1])
|
; txt.print_uwhex(value, true)
|
||||||
txt.print_uwhex(warray[1],true)
|
; txt.nl()
|
||||||
txt.nl()
|
; upperb = msb(warray[1])
|
||||||
|
; lowerb = lsb(warray[1])
|
||||||
|
; txt.print_ubhex(upperb, true)
|
||||||
|
; txt.print_ubhex(lowerb, false)
|
||||||
|
; txt.nl()
|
||||||
|
; ubyte index=1
|
||||||
|
; upperb = msb(warray[index])
|
||||||
|
; lowerb = lsb(warray[index])
|
||||||
|
; txt.print_ubhex(upperb, true)
|
||||||
|
; txt.print_ubhex(lowerb, false)
|
||||||
|
; txt.nl()
|
||||||
|
; swap(other, value)
|
||||||
|
; txt.print_uwhex(value,true)
|
||||||
|
; txt.nl()
|
||||||
|
; txt.nl()
|
||||||
|
;
|
||||||
|
; pokew($1000, $ab98)
|
||||||
|
; txt.print_ubhex(@($1000),true)
|
||||||
|
; txt.print_ubhex(@($1001),false)
|
||||||
|
; txt.nl()
|
||||||
|
; txt.print_uwhex(peekw($1000),true)
|
||||||
|
; txt.nl()
|
||||||
|
; swap(@($1000), @($1001))
|
||||||
|
; txt.print_uwhex(peekw($1000),true)
|
||||||
|
; txt.nl()
|
||||||
|
; swap(warray[0], warray[1])
|
||||||
|
; txt.print_uwhex(warray[1],true)
|
||||||
|
; txt.nl()
|
||||||
|
|
||||||
; ; a "pixelshader":
|
; ; a "pixelshader":
|
||||||
; void syscall1(8, 0) ; enable lo res creen
|
; void syscall1(8, 0) ; enable lo res creen
|
||||||
|
Loading…
Reference in New Issue
Block a user