working on vm

This commit is contained in:
Irmen de Jong
2022-03-28 00:18:56 +02:00
parent 30cbb6c9a8
commit bb1bf6a88c
12 changed files with 121 additions and 81 deletions
@@ -1,5 +1,6 @@
package prog8.codegen.virtual
import prog8.code.StStaticVariable
import prog8.code.SymbolTable
import prog8.code.ast.*
import prog8.code.core.*
@@ -58,7 +59,7 @@ class CodeGen(internal val program: PtProgram,
is PtJump -> translate(node)
is PtWhen -> TODO("when")
is PtPipe -> expressionEval.translate(node, regUsage.nextFree(), regUsage)
is PtForLoop -> TODO("for-loop")
is PtForLoop -> translate(node, regUsage)
is PtIfElse -> translate(node, regUsage)
is PtPostIncrDecr -> translate(node, regUsage)
is PtRepeatLoop -> translate(node, regUsage)
@@ -90,6 +91,30 @@ class CodeGen(internal val program: PtProgram,
return code
}
private fun translate(forLoop: PtForLoop, regUsage: RegisterUsage): VmCodeChunk {
val loopvar = symbolTable.lookup(forLoop.variable.targetName) as StStaticVariable
val iterable = forLoop.iterable
val code = VmCodeChunk()
when(iterable) {
is PtRange -> {
println("forloop ${loopvar.dt} ${loopvar.scopedName} in range ${iterable} ")
iterable.printIndented(0)
TODO()
}
is PtIdentifier -> {
val address = allocations.get(iterable.targetName)
val variable = symbolTable.lookup(iterable.targetName) as StStaticVariable
val length = variable.length!!
println("forloop ${loopvar.dt} ${loopvar.scopedName} in $iterable @${address.toHex()} ${length}")
val indexReg = regUsage.nextFree()
val loopvarReg = regUsage.nextFree()
TODO()
}
else -> throw AssemblyError("weird for iterable")
}
return code
}
private fun translate(ifElse: PtIfElse, regUsage: RegisterUsage): VmCodeChunk {
var branch = Opcode.BZ
var condition = ifElse.condition
@@ -83,14 +83,14 @@ internal class ExpressionGen(val codeGen: CodeGen) {
val call = PtFunctionCall(listOf("prog8_lib", "bytearray_contains"), false, DataType.UBYTE, check.position)
call.children.add(check.element)
call.children.add(check.iterable)
call.children.add(PtNumber(DataType.UBYTE, iterable.arraysize!!.toDouble(), iterable.position))
call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position))
code += translate(call, resultRegister, regUsage)
}
DataType.ARRAY_UW, DataType.ARRAY_W -> {
val call = PtFunctionCall(listOf("prog8_lib", "wordarray_contains"), false, DataType.UBYTE, check.position)
call.children.add(check.element)
call.children.add(check.iterable)
call.children.add(PtNumber(DataType.UBYTE, iterable.arraysize!!.toDouble(), iterable.position))
call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position))
code += translate(call, resultRegister, regUsage)
}
DataType.ARRAY_F -> TODO("containment check in float-array")
@@ -204,21 +204,17 @@ internal class ExpressionGen(val codeGen: CodeGen) {
}
DataType.FLOAT -> {
TODO("floating point not yet supported")
when(cast.value.type) {
DataType.BYTE -> {
// TODO("byte -> float")
}
DataType.UBYTE -> {
// TODO("ubyte -> float")
}
DataType.WORD -> {
// TODO("word -> float")
}
DataType.UWORD -> {
// TODO("uword -> float")
}
else -> throw AssemblyError("weird cast value type")
}
// when(cast.value.type) {
// DataType.BYTE -> {
// }
// DataType.UBYTE -> {
// }
// DataType.WORD -> {
// }
// DataType.UWORD -> {
// }
// else -> throw AssemblyError("weird cast value type")
// }
}
else -> throw AssemblyError("weird cast type")
}
@@ -229,7 +225,8 @@ internal class ExpressionGen(val codeGen: CodeGen) {
val code = VmCodeChunk()
val leftResultReg = regUsage.nextFree()
val rightResultReg = regUsage.nextFree()
// TODO: optimized codegen when left or right operand is known 0 or 1 or whatever.
// TODO: optimized codegen when left or right operand is known 0 or 1 or whatever. But only if this would result in a different opcode such as ADD 1 -> INC, MUL 1 -> NOP
// actually optimizing the code should not be done here but in a tailored code optimizer step.
val leftCode = translateExpression(binExpr.left, leftResultReg, regUsage)
val rightCode = translateExpression(binExpr.right, rightResultReg, regUsage)
code += leftCode
@@ -288,7 +285,7 @@ internal class ExpressionGen(val codeGen: CodeGen) {
val ins = if(binExpr.type in SignedDatatypes) Opcode.SGES else Opcode.SGE
code += VmCodeInstruction(Instruction(ins, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg))
}
else -> TODO("operator ${binExpr.operator}")
else -> throw AssemblyError("weird operator ${binExpr.operator}")
}
return code
}
@@ -357,9 +354,11 @@ internal class ExpressionGen(val codeGen: CodeGen) {
"msb" -> {
code += translateExpression(call.args.single(), resultRegister, regUsage)
code += VmCodeInstruction(Instruction(Opcode.SWAP, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister))
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
}
"lsb" -> {
code += translateExpression(call.args.single(), resultRegister, regUsage)
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
}
"memory" -> {
val name = (call.args[0] as PtString).value
@@ -391,12 +390,6 @@ internal class ExpressionGen(val codeGen: CodeGen) {
code += translateExpression(call.args.single(), addressReg, regUsage)
code += VmCodeInstruction(Instruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2=addressReg))
}
"memory" -> {
val memname = (call.args[0] as PtString).value
val size = (call.args[1] as PtNumber).number.toInt()
val align = (call.args[2] as PtNumber).number.toInt()
TODO("memory '$memname', $size, $align")
}
else -> {
TODO("builtinfunc ${call.name}")
// code += VmCodeInstruction(Instruction(Opcode.NOP))
@@ -19,7 +19,7 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg
when (variable.dt) {
DataType.STR -> variable.initialStringValue!!.first.length + 1 // include the zero byte
in NumericDatatypes -> program.memsizer.memorySize(variable.dt)
in ArrayDatatypes -> program.memsizer.memorySize(variable.dt, variable.arraysize!!)
in ArrayDatatypes -> program.memsizer.memorySize(variable.dt, variable.length!!)
else -> throw InternalCompilerException("weird dt")
}
@@ -55,14 +55,14 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg
if(variable.initialArrayValue!=null) {
variable.initialArrayValue!!.joinToString(",") { it.number!!.toString() }
} else {
(1..variable.arraysize!!).joinToString(",") { "0" }
(1..variable.length!!).joinToString(",") { "0" }
}
}
in ArrayDatatypes -> {
if(variable.initialArrayValue!==null) {
variable.initialArrayValue!!.joinToString(",") { it.number!!.toHex() }
} else {
(1..variable.arraysize!!).joinToString(",") { "0" }
(1..variable.length!!).joinToString(",") { "0" }
}
}
else -> throw InternalCompilerException("weird dt")