diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index d8e2604b4..95ed20830 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -8,7 +8,7 @@ import prog8.code.core.SignedDatatypes import prog8.intermediate.IRCodeChunk import prog8.intermediate.IRInstruction import prog8.intermediate.Opcode -import prog8.intermediate.VmDataType +import prog8.intermediate.IRDataType internal class AssignmentGen(private val codeGen: IRCodeGen, private val expressionEval: ExpressionGen) { @@ -49,7 +49,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express value: PtExpression, origAssign: PtAssignment ): IRCodeChunk { - val vmDt = codeGen.vmType(value.type) + val vmDt = codeGen.irType(value.type) val code = IRCodeChunk(origAssign.position) when(value) { is PtIdentifier -> return code // do nothing, x=x null assignment. @@ -61,7 +61,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express code // do nothing, mem=mem null assignment. else { // read and write a (i/o) memory location to itself. - val tempReg = codeGen.vmRegisters.nextFree() + val tempReg = codeGen.registers.nextFree() code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, value = address) code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, value = address) code @@ -76,7 +76,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express value: PtExpression, origAssign: PtAssignment ): IRCodeChunk { - val vmDt = codeGen.vmType(value.type) + val vmDt = codeGen.irType(value.type) val code = IRCodeChunk(origAssign.position) when(value) { is PtIdentifier -> return code // do nothing, x=x null assignment. @@ -84,7 +84,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express is PtPrefix -> return inplacePrefix(value.operator, vmDt, null, symbol, value.position) is PtBinaryExpression -> return inplaceBinexpr(value.operator, value.right, vmDt, value.type in SignedDatatypes, null, symbol, origAssign) is PtMemoryByte -> { - val tempReg = codeGen.vmRegisters.nextFree() + val tempReg = codeGen.registers.nextFree() code += IRInstruction(Opcode.LOADM, vmDt, reg1 = tempReg, labelSymbol = symbol) code += IRInstruction(Opcode.STOREM, vmDt, reg1 = tempReg, labelSymbol = symbol) return code @@ -102,7 +102,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express private fun inplaceBinexpr( operator: String, operand: PtExpression, - vmDt: VmDataType, + vmDt: IRDataType, signed: Boolean, knownAddress: Int?, symbol: String?, @@ -139,7 +139,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express return fallbackAssign(origAssign) } - private fun inplacePrefix(operator: String, vmDt: VmDataType, knownAddress: Int?, addressSymbol: String?, position: Position): IRCodeChunk { + private fun inplacePrefix(operator: String, vmDt: IRDataType, knownAddress: Int?, addressSymbol: String?, position: Position): IRCodeChunk { val code= IRCodeChunk(position) when(operator) { "+" -> { } @@ -150,8 +150,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express IRInstruction(Opcode.NEGM, vmDt, labelSymbol = addressSymbol) } "~" -> { - val regMask = codeGen.vmRegisters.nextFree() - val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff + val regMask = codeGen.registers.nextFree() + val mask = if(vmDt==IRDataType.BYTE) 0x00ff else 0xffff code += IRInstruction(Opcode.LOAD, vmDt, reg1=regMask, value = mask) code += if(knownAddress!=null) IRInstruction(Opcode.XORM, vmDt, reg1=regMask, value = knownAddress) @@ -168,7 +168,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express val ident = assignment.target.identifier val memory = assignment.target.memory val array = assignment.target.array - val vmDt = codeGen.vmType(assignment.value.type) + val vmDt = codeGen.irType(assignment.value.type) val code = IRCodeChunk(assignment.position) var resultRegister = -1 @@ -176,14 +176,14 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express val zero = codeGen.isZero(assignment.value) if(!zero) { // calculate the assignment value - if (vmDt == VmDataType.FLOAT) { - resultFpRegister = codeGen.vmRegisters.nextFreeFloat() + if (vmDt == IRDataType.FLOAT) { + resultFpRegister = codeGen.registers.nextFreeFloat() code += expressionEval.translateExpression(assignment.value, -1, resultFpRegister) } else { resultRegister = if (assignment.value is PtMachineRegister) { (assignment.value as PtMachineRegister).register } else { - val reg = codeGen.vmRegisters.nextFree() + val reg = codeGen.registers.nextFree() code += expressionEval.translateExpression(assignment.value, reg, -1) reg } @@ -194,7 +194,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express code += if(zero) { IRInstruction(Opcode.STOREZM, vmDt, labelSymbol = symbol) } else { - if (vmDt == VmDataType.FLOAT) + if (vmDt == IRDataType.FLOAT) IRInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol) else IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = symbol) @@ -210,11 +210,11 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express throw AssemblyError("non-array var indexing requires bytes dt") if(array.index.type!=DataType.UBYTE) throw AssemblyError("non-array var indexing requires bytes index") - val idxReg = codeGen.vmRegisters.nextFree() + val idxReg = codeGen.registers.nextFree() code += expressionEval.translateExpression(array.index, idxReg, -1) if(zero) { // there's no STOREZIX instruction - resultRegister = codeGen.vmRegisters.nextFree() + resultRegister = codeGen.registers.nextFree() code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=0) } code += IRInstruction(Opcode.STOREIX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = variable) @@ -227,17 +227,17 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express val offset = fixedIndex*itemsize code += IRInstruction(Opcode.STOREZM, vmDt, labelSymbol = "$variable+$offset") } else { - val indexReg = codeGen.vmRegisters.nextFree() + val indexReg = codeGen.registers.nextFree() code += loadIndexReg(array, itemsize, indexReg, array.position) code += IRInstruction(Opcode.STOREZX, vmDt, reg1=indexReg, labelSymbol = variable) } } else { - if(vmDt== VmDataType.FLOAT) { + if(vmDt== IRDataType.FLOAT) { if(fixedIndex!=null) { val offset = fixedIndex*itemsize code += IRInstruction(Opcode.STOREM, vmDt, fpReg1 = resultFpRegister, labelSymbol = "$variable+$offset") } else { - val indexReg = codeGen.vmRegisters.nextFree() + val indexReg = codeGen.registers.nextFree() code += loadIndexReg(array, itemsize, indexReg, array.position) code += IRInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable) } @@ -246,7 +246,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express val offset = fixedIndex*itemsize code += IRInstruction(Opcode.STOREM, vmDt, reg1 = resultRegister, labelSymbol = "$variable+$offset") } else { - val indexReg = codeGen.vmRegisters.nextFree() + val indexReg = codeGen.registers.nextFree() code += loadIndexReg(array, itemsize, indexReg, array.position) code += IRInstruction(Opcode.STOREX, vmDt, reg1 = resultRegister, reg2=indexReg, labelSymbol = variable) } @@ -254,12 +254,12 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express } } else if(memory!=null) { - require(vmDt== VmDataType.BYTE) + require(vmDt== IRDataType.BYTE) if(zero) { if(memory.address is PtNumber) { code += IRInstruction(Opcode.STOREZM, vmDt, value=(memory.address as PtNumber).number.toInt()) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += expressionEval.translateExpression(memory.address, addressReg, -1) code += IRInstruction(Opcode.STOREZI, vmDt, reg1=addressReg) } @@ -267,7 +267,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express if(memory.address is PtNumber) { code += IRInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt()) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += expressionEval.translateExpression(memory.address, addressReg, -1) code += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg) } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 647c56bbe..903feb67b 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -51,11 +51,11 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe private fun funcCmp(call: PtBuiltinFunctionCall): IRCodeChunk { val code = IRCodeChunk(call.position) - val leftRegister = codeGen.vmRegisters.nextFree() - val rightRegister = codeGen.vmRegisters.nextFree() + val leftRegister = codeGen.registers.nextFree() + val rightRegister = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args[0], leftRegister, -1) code += exprGen.translateExpression(call.args[1], rightRegister, -1) - code += IRInstruction(Opcode.CMP, codeGen.vmType(call.args[0].type), reg1=leftRegister, reg2=rightRegister) + code += IRInstruction(Opcode.CMP, codeGen.irType(call.args[0].type), reg1=leftRegister, reg2=rightRegister) return code } @@ -73,10 +73,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe else -> throw IllegalArgumentException("weird type") } code += exprGen.translateExpression(call.args[0], 0, -1) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1 = 1, value = array.length) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = 1, value = array.length) code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal) if (resultRegister != 0) - code += IRInstruction(Opcode.LOADR, VmDataType.BYTE, reg1 = resultRegister, reg2 = 0) + code += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1 = resultRegister, reg2 = 0) return code } @@ -94,10 +94,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } val code = IRCodeChunk(call.position) code += exprGen.translateExpression(call.args[0], 0, -1) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=1, value=array.length) code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal) if(resultRegister!=0) - code += IRInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0) + code += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=resultRegister, reg2=0) return code } @@ -108,25 +108,25 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe code += exprGen.translateExpression(call.args[0], resultRegister, -1) when (sourceDt) { DataType.UBYTE -> { - code += IRInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister) + code += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=resultRegister) } DataType.BYTE -> { val notNegativeLabel = codeGen.createLabelName() - val compareReg = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=compareReg, reg2=resultRegister) - code += IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=compareReg, value=0x80) - code += IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel) - code += IRInstruction(Opcode.NEG, VmDataType.BYTE, reg1=resultRegister) - code += IRInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister) + val compareReg = codeGen.registers.nextFree() + code += IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=compareReg, reg2=resultRegister) + code += IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=compareReg, value=0x80) + code += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=compareReg, labelSymbol = notNegativeLabel) + code += IRInstruction(Opcode.NEG, IRDataType.BYTE, reg1=resultRegister) + code += IRInstruction(Opcode.EXT, IRDataType.BYTE, reg1=resultRegister) code += IRCodeLabel(notNegativeLabel) } DataType.WORD -> { val notNegativeLabel = codeGen.createLabelName() - val compareReg = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.LOADR, VmDataType.WORD, reg1=compareReg, reg2=resultRegister) - code += IRInstruction(Opcode.AND, VmDataType.WORD, reg1=compareReg, value=0x8000) - code += IRInstruction(Opcode.BZ, VmDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel) - code += IRInstruction(Opcode.NEG, VmDataType.WORD, reg1=resultRegister) + val compareReg = codeGen.registers.nextFree() + code += IRInstruction(Opcode.LOADR, IRDataType.WORD, reg1=compareReg, reg2=resultRegister) + code += IRInstruction(Opcode.AND, IRDataType.WORD, reg1=compareReg, value=0x8000) + code += IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=compareReg, labelSymbol = notNegativeLabel) + code += IRInstruction(Opcode.NEG, IRDataType.WORD, reg1=resultRegister) code += IRCodeLabel(notNegativeLabel) } else -> throw AssemblyError("weird type") @@ -137,49 +137,49 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(call.position) - val reg = codeGen.vmRegisters.nextFree() + val reg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args.single(), reg, -1) - code += IRInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=reg) + code += IRInstruction(Opcode.SGN, codeGen.irType(call.type), reg1=resultRegister, reg2=reg) return code } private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(call.position) - val reg = codeGen.vmRegisters.nextFree() + val reg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args.single(), reg, -1) - code += IRInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=reg) + code += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=resultRegister, reg2=reg) return code } private fun funcPop(call: PtBuiltinFunctionCall): IRCodeChunk { val code = IRCodeChunk(call.position) - val reg = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.POP, VmDataType.BYTE, reg1=reg) + val reg = codeGen.registers.nextFree() + code += IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=reg) code += assignRegisterTo(call.args.single(), reg) return code } private fun funcPopw(call: PtBuiltinFunctionCall): IRCodeChunk { val code = IRCodeChunk(call.position) - val reg = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.POP, VmDataType.WORD, reg1=reg) + val reg = codeGen.registers.nextFree() + code += IRInstruction(Opcode.POP, IRDataType.WORD, reg1=reg) code += assignRegisterTo(call.args.single(), reg) return code } private fun funcPush(call: PtBuiltinFunctionCall): IRCodeChunk { val code = IRCodeChunk(call.position) - val reg = codeGen.vmRegisters.nextFree() + val reg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args.single(), reg, -1) - code += IRInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=reg) + code += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=reg) return code } private fun funcPushw(call: PtBuiltinFunctionCall): IRCodeChunk { val code = IRCodeChunk(call.position) - val reg = codeGen.vmRegisters.nextFree() + val reg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args.single(), reg, -1) - code += IRInstruction(Opcode.PUSH, VmDataType.WORD, reg1=reg) + code += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1=reg) return code } @@ -195,7 +195,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } val code = IRCodeChunk(call.position) code += exprGen.translateExpression(call.args[0], 0, -1) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=1, value=array.length) code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal) return code } @@ -215,17 +215,17 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } val code = IRCodeChunk(call.position) code += exprGen.translateExpression(call.args[0], 0, -1) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=1, value=array.length) code += IRInstruction(Opcode.SYSCALL, value=syscall.ordinal) return code } private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { - val msbReg = codeGen.vmRegisters.nextFree() + val msbReg = codeGen.registers.nextFree() val code = IRCodeChunk(call.position) code += exprGen.translateExpression(call.args[0], msbReg, -1) code += exprGen.translateExpression(call.args[1], resultRegister, -1) - code += IRInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg) + code += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1=resultRegister, reg2=msbReg) return code } @@ -234,23 +234,23 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe if(codeGen.isZero(call.args[1])) { if (call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() - code += IRInstruction(Opcode.STOREZM, VmDataType.WORD, value = address) + code += IRInstruction(Opcode.STOREZM, IRDataType.WORD, value = address) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args[0], addressReg, -1) - code += IRInstruction(Opcode.STOREZI, VmDataType.WORD, reg2 = addressReg) + code += IRInstruction(Opcode.STOREZI, IRDataType.WORD, reg2 = addressReg) } } else { - val valueReg = codeGen.vmRegisters.nextFree() + val valueReg = codeGen.registers.nextFree() if (call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() code += exprGen.translateExpression(call.args[1], valueReg, -1) - code += IRInstruction(Opcode.STOREM, VmDataType.WORD, reg1 = valueReg, value = address) + code += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = valueReg, value = address) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args[0], addressReg, -1) code += exprGen.translateExpression(call.args[1], valueReg, -1) - code += IRInstruction(Opcode.STOREI, VmDataType.WORD, reg1 = valueReg, reg2 = addressReg) + code += IRInstruction(Opcode.STOREI, IRDataType.WORD, reg1 = valueReg, reg2 = addressReg) } } return code @@ -261,23 +261,23 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe if(codeGen.isZero(call.args[1])) { if (call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() - code += IRInstruction(Opcode.STOREZM, VmDataType.BYTE, value = address) + code += IRInstruction(Opcode.STOREZM, IRDataType.BYTE, value = address) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args[0], addressReg, -1) - code += IRInstruction(Opcode.STOREZI, VmDataType.BYTE, reg2 = addressReg) + code += IRInstruction(Opcode.STOREZI, IRDataType.BYTE, reg2 = addressReg) } } else { - val valueReg = codeGen.vmRegisters.nextFree() + val valueReg = codeGen.registers.nextFree() if (call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() code += exprGen.translateExpression(call.args[1], valueReg, -1) - code += IRInstruction(Opcode.STOREM, VmDataType.BYTE, reg1 = valueReg, value = address) + code += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = valueReg, value = address) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args[0], addressReg, -1) code += exprGen.translateExpression(call.args[1], valueReg, -1) - code += IRInstruction(Opcode.STOREI, VmDataType.BYTE, reg1 = valueReg, reg2 = addressReg) + code += IRInstruction(Opcode.STOREI, IRDataType.BYTE, reg1 = valueReg, reg2 = addressReg) } } return code @@ -287,11 +287,11 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe val code = IRCodeChunk(call.position) if(call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() - code += IRInstruction(Opcode.LOADM, VmDataType.WORD, reg1 = resultRegister, value = address) + code += IRInstruction(Opcode.LOADM, IRDataType.WORD, reg1 = resultRegister, value = address) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args.single(), addressReg, -1) - code += IRInstruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2 = addressReg) + code += IRInstruction(Opcode.LOADI, IRDataType.WORD, reg1 = resultRegister, reg2 = addressReg) } return code } @@ -300,31 +300,31 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe val code = IRCodeChunk(call.position) if(call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() - code += IRInstruction(Opcode.LOADM, VmDataType.BYTE, reg1 = resultRegister, value = address) + code += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1 = resultRegister, value = address) } else { - val addressReg = codeGen.vmRegisters.nextFree() + val addressReg = codeGen.registers.nextFree() code += exprGen.translateExpression(call.args.single(), addressReg, -1) - code += IRInstruction(Opcode.LOADI, VmDataType.BYTE, reg1 = resultRegister, reg2 = addressReg) + code += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = resultRegister, reg2 = addressReg) } return code } private fun funcRnd(resultRegister: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) - code += IRInstruction(Opcode.RND, VmDataType.BYTE, reg1=resultRegister) + code += IRInstruction(Opcode.RND, IRDataType.BYTE, reg1=resultRegister) return code } private fun funcRndw(resultRegister: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) - code += IRInstruction(Opcode.RND, VmDataType.WORD, reg1=resultRegister) + code += IRInstruction(Opcode.RND, IRDataType.WORD, reg1=resultRegister) return code } private fun funcMemory(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { val name = (call.args[0] as PtString).value val code = IRCodeChunk(call.position) - code += IRInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = "prog8_slabs.prog8_memoryslab_$name") + code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=resultRegister, labelSymbol = "prog8_slabs.prog8_memoryslab_$name") return code } @@ -338,13 +338,13 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(call.position) code += exprGen.translateExpression(call.args.single(), resultRegister, -1) - code += IRInstruction(Opcode.MSIG, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister) + code += IRInstruction(Opcode.MSIG, IRDataType.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. return code } private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { - val vmDt = codeGen.vmType(call.args[0].type) + val vmDt = codeGen.irType(call.args[0].type) val code = IRCodeChunk(call.position) code += exprGen.translateExpression(call.args[0], resultRegister, -1) code += IRInstruction(opcode, vmDt, reg1=resultRegister) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index 3b9cd7c1c..ba500a112 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -10,29 +10,29 @@ import prog8.intermediate.* internal class ExpressionGen(private val codeGen: IRCodeGen) { fun translateExpression(expr: PtExpression, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { - require(codeGen.vmRegisters.peekNext() > resultRegister) + require(codeGen.registers.peekNext() > resultRegister) val code = IRCodeChunk(expr.position) when (expr) { is PtMachineRegister -> { if(resultRegister!=expr.register) { - val vmDt = codeGen.vmType(expr.type) + val vmDt = codeGen.irType(expr.type) code += IRInstruction(Opcode.LOADR, vmDt, reg1=resultRegister, reg2=expr.register) } } is PtNumber -> { - val vmDt = codeGen.vmType(expr.type) - code += if(vmDt==VmDataType.FLOAT) + val vmDt = codeGen.irType(expr.type) + code += if(vmDt==IRDataType.FLOAT) IRInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat()) else IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=expr.number.toInt()) } is PtIdentifier -> { - val vmDt = codeGen.vmType(expr.type) + val vmDt = codeGen.irType(expr.type) val symbol = expr.targetName.joinToString(".") code += if (expr.type in PassByValueDatatypes) { - if(vmDt==VmDataType.FLOAT) + if(vmDt==IRDataType.FLOAT) IRInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, labelSymbol = symbol) else IRInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, labelSymbol = symbol) @@ -42,7 +42,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } is PtAddressOf -> { - val vmDt = codeGen.vmType(expr.type) + val vmDt = codeGen.irType(expr.type) val symbol = expr.identifier.targetName.joinToString(".") // note: LOAD gets you the address of the symbol, whereas LOADM would get you the value stored at that location code += IRInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, labelSymbol = symbol) @@ -50,11 +50,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { is PtMemoryByte -> { if(expr.address is PtNumber) { val address = (expr.address as PtNumber).number.toInt() - code += IRInstruction(Opcode.LOADM, VmDataType.BYTE, reg1=resultRegister, value = address) + code += IRInstruction(Opcode.LOADM, IRDataType.BYTE, reg1=resultRegister, value = address) } else { - val addressRegister = codeGen.vmRegisters.nextFree() + val addressRegister = codeGen.registers.nextFree() code += translateExpression(expr.address, addressRegister, -1) - code += IRInstruction(Opcode.LOADI, VmDataType.BYTE, reg1=resultRegister, reg2=addressRegister) + code += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1=resultRegister, reg2=addressRegister) } } is PtTypeCast -> code += translate(expr, resultRegister, resultFpRegister) @@ -105,9 +105,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { private fun translate(arrayIx: PtArrayIndexer, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { val eltSize = codeGen.program.memsizer.memorySize(arrayIx.type) - val vmDt = codeGen.vmType(arrayIx.type) + val vmDt = codeGen.irType(arrayIx.type) val code = IRCodeChunk(arrayIx.position) - val idxReg = codeGen.vmRegisters.nextFree() + val idxReg = codeGen.registers.nextFree() val arrayVarSymbol = arrayIx.variable.targetName.joinToString(".") if(arrayIx.variable.type==DataType.UWORD) { @@ -123,16 +123,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { if(arrayIx.index is PtNumber) { val memOffset = ((arrayIx.index as PtNumber).number.toInt() * eltSize).toString() - if(vmDt==VmDataType.FLOAT) - code += IRInstruction(Opcode.LOADM, VmDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset") + if(vmDt==IRDataType.FLOAT) + code += IRInstruction(Opcode.LOADM, IRDataType.FLOAT, fpReg1=resultFpRegister, labelSymbol = "$arrayVarSymbol+$memOffset") else code += IRInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, labelSymbol = "$arrayVarSymbol+$memOffset") } else { code += translateExpression(arrayIx.index, idxReg, -1) if(eltSize>1) - code += codeGen.multiplyByConst(VmDataType.BYTE, idxReg, eltSize, arrayIx.position) - if(vmDt==VmDataType.FLOAT) - code += IRInstruction(Opcode.LOADX, VmDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol) + code += codeGen.multiplyByConst(IRDataType.BYTE, idxReg, eltSize, arrayIx.position) + if(vmDt==IRDataType.FLOAT) + code += IRInstruction(Opcode.LOADX, IRDataType.FLOAT, fpReg1 = resultFpRegister, reg1=idxReg, labelSymbol = arrayVarSymbol) else code += IRInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, labelSymbol = arrayVarSymbol) } @@ -142,14 +142,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { private fun translate(expr: PtPrefix, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(expr.position) code += translateExpression(expr.value, resultRegister, -1) - val vmDt = codeGen.vmType(expr.type) + val vmDt = codeGen.irType(expr.type) when(expr.operator) { "+" -> { } "-" -> { code += IRInstruction(Opcode.NEG, vmDt, reg1=resultRegister) } "~" -> { - val mask = if(vmDt==VmDataType.BYTE) 0x00ff else 0xffff + val mask = if(vmDt==IRDataType.BYTE) 0x00ff else 0xffff code += IRInstruction(Opcode.XOR, vmDt, reg1=resultRegister, value=mask) } else -> throw AssemblyError("weird prefix operator") @@ -161,8 +161,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val code = IRCodeChunk(cast.position) if(cast.type==cast.value.type) return code - val actualResultFpReg = if(predefinedResultFpRegister>=0) predefinedResultFpRegister else codeGen.vmRegisters.nextFreeFloat() - val actualResultReg = if(predefinedResultRegister>=0) predefinedResultRegister else codeGen.vmRegisters.nextFree() + val actualResultFpReg = if(predefinedResultFpRegister>=0) predefinedResultFpRegister else codeGen.registers.nextFreeFloat() + val actualResultReg = if(predefinedResultRegister>=0) predefinedResultRegister else codeGen.registers.nextFree() if(cast.value.type==DataType.FLOAT) { // a cast from float to integer, so evaluate the value into a float register first code += translateExpression(cast.value, -1, actualResultFpReg) @@ -173,14 +173,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { DataType.UBYTE -> { when(cast.value.type) { DataType.BYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ } - DataType.FLOAT -> code += IRInstruction(Opcode.FTOUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + DataType.FLOAT -> code += IRInstruction(Opcode.FTOUB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) else -> throw AssemblyError("weird cast value type") } } DataType.BYTE -> { when(cast.value.type) { DataType.UBYTE, DataType.UWORD, DataType.WORD -> { /* just keep the LSB as it is */ } - DataType.FLOAT -> code += IRInstruction(Opcode.FTOSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + DataType.FLOAT -> code += IRInstruction(Opcode.FTOSB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) else -> throw AssemblyError("weird cast value type") } } @@ -188,15 +188,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { when(cast.value.type) { DataType.BYTE -> { // byte -> uword: sign extend - code += IRInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg) + code += IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg) } DataType.UBYTE -> { // ubyte -> uword: sign extend - code += IRInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg) + code += IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg) } DataType.WORD -> { } DataType.FLOAT -> { - code += IRInstruction(Opcode.FTOUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + code += IRInstruction(Opcode.FTOUW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) } else -> throw AssemblyError("weird cast value type") } @@ -205,15 +205,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { when(cast.value.type) { DataType.BYTE -> { // byte -> word: sign extend - code += IRInstruction(Opcode.EXTS, type = VmDataType.BYTE, reg1 = actualResultReg) + code += IRInstruction(Opcode.EXTS, type = IRDataType.BYTE, reg1 = actualResultReg) } DataType.UBYTE -> { // byte -> word: sign extend - code += IRInstruction(Opcode.EXT, type = VmDataType.BYTE, reg1 = actualResultReg) + code += IRInstruction(Opcode.EXT, type = IRDataType.BYTE, reg1 = actualResultReg) } DataType.UWORD -> { } DataType.FLOAT -> { - code += IRInstruction(Opcode.FTOSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + code += IRInstruction(Opcode.FTOSW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) } else -> throw AssemblyError("weird cast value type") } @@ -221,16 +221,16 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { DataType.FLOAT -> { code += when(cast.value.type) { DataType.UBYTE -> { - IRInstruction(Opcode.FFROMUB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + IRInstruction(Opcode.FFROMUB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) } DataType.BYTE -> { - IRInstruction(Opcode.FFROMSB, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + IRInstruction(Opcode.FFROMSB, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) } DataType.UWORD -> { - IRInstruction(Opcode.FFROMUW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + IRInstruction(Opcode.FFROMUW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) } DataType.WORD -> { - IRInstruction(Opcode.FFROMSW, VmDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) + IRInstruction(Opcode.FFROMSW, IRDataType.FLOAT, reg1=actualResultReg, fpReg1 = actualResultFpReg) } else -> throw AssemblyError("weird cast value type") } @@ -241,7 +241,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } private fun translate(binExpr: PtBinaryExpression, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { - val vmDt = codeGen.vmType(binExpr.left.type) + val vmDt = codeGen.irType(binExpr.left.type) val signed = binExpr.left.type in SignedDatatypes return when(binExpr.operator) { "+" -> operatorPlus(binExpr, vmDt, resultRegister, resultFpRegister) @@ -266,40 +266,40 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { private fun operatorGreaterThan( binExpr: PtBinaryExpression, - vmDt: VmDataType, + vmDt: IRDataType, resultRegister: Int, signed: Boolean, greaterEquals: Boolean ): IRCodeChunk { val code = IRCodeChunk(binExpr.position) - if(vmDt==VmDataType.FLOAT) { - val leftFpReg = codeGen.vmRegisters.nextFreeFloat() - val rightFpReg = codeGen.vmRegisters.nextFreeFloat() - val zeroRegister = codeGen.vmRegisters.nextFree() + if(vmDt==IRDataType.FLOAT) { + val leftFpReg = codeGen.registers.nextFreeFloat() + val rightFpReg = codeGen.registers.nextFreeFloat() + val zeroRegister = codeGen.registers.nextFree() code += translateExpression(binExpr.left, -1, leftFpReg) code += translateExpression(binExpr.right, -1, rightFpReg) - code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0) + code += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0) val ins = if (signed) { if (greaterEquals) Opcode.SGES else Opcode.SGTS } else { if (greaterEquals) Opcode.SGE else Opcode.SGT } - code += IRInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister) + code += IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister) } else { if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) { val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY) comparisonCall.children.add(binExpr.left) comparisonCall.children.add(binExpr.right) code += translate(comparisonCall, resultRegister, -1) - val zeroRegister = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0) + val zeroRegister = codeGen.registers.nextFree() + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0) code += if(greaterEquals) - IRInstruction(Opcode.SGES, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) + IRInstruction(Opcode.SGES, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) else - IRInstruction(Opcode.SGTS, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) + IRInstruction(Opcode.SGTS, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) val ins = if (signed) { @@ -315,40 +315,40 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { private fun operatorLessThan( binExpr: PtBinaryExpression, - vmDt: VmDataType, + vmDt: IRDataType, resultRegister: Int, signed: Boolean, lessEquals: Boolean ): IRCodeChunk { val code = IRCodeChunk(binExpr.position) - if(vmDt==VmDataType.FLOAT) { - val leftFpReg = codeGen.vmRegisters.nextFreeFloat() - val rightFpReg = codeGen.vmRegisters.nextFreeFloat() - val zeroRegister = codeGen.vmRegisters.nextFree() + if(vmDt==IRDataType.FLOAT) { + val leftFpReg = codeGen.registers.nextFreeFloat() + val rightFpReg = codeGen.registers.nextFreeFloat() + val zeroRegister = codeGen.registers.nextFree() code += translateExpression(binExpr.left, -1, leftFpReg) code += translateExpression(binExpr.right, -1, rightFpReg) - code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0) + code += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0) val ins = if (signed) { if (lessEquals) Opcode.SLES else Opcode.SLTS } else { if (lessEquals) Opcode.SLE else Opcode.SLT } - code += IRInstruction(ins, VmDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister) + code += IRInstruction(ins, IRDataType.BYTE, reg1 = resultRegister, reg2 = zeroRegister) } else { if(binExpr.left.type==DataType.STR && binExpr.right.type==DataType.STR) { val comparisonCall = PtFunctionCall(listOf("prog8_lib", "string_compare"), false, DataType.BYTE, Position.DUMMY) comparisonCall.children.add(binExpr.left) comparisonCall.children.add(binExpr.right) code += translate(comparisonCall, resultRegister, -1) - val zeroRegister = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=zeroRegister, value=0) + val zeroRegister = codeGen.registers.nextFree() + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=zeroRegister, value=0) code += if(lessEquals) - IRInstruction(Opcode.SLES, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) + IRInstruction(Opcode.SLES, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) else - IRInstruction(Opcode.SLTS, VmDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) + IRInstruction(Opcode.SLTS, IRDataType.BYTE, reg1=resultRegister, reg2=zeroRegister) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) val ins = if (signed) { @@ -362,22 +362,22 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorEquals(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, notEquals: Boolean): IRCodeChunk { + private fun operatorEquals(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int, notEquals: Boolean): IRCodeChunk { val code = IRCodeChunk(binExpr.position) - if(vmDt==VmDataType.FLOAT) { - val leftFpReg = codeGen.vmRegisters.nextFreeFloat() - val rightFpReg = codeGen.vmRegisters.nextFreeFloat() + if(vmDt==IRDataType.FLOAT) { + val leftFpReg = codeGen.registers.nextFreeFloat() + val rightFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(binExpr.left, -1, leftFpReg) code += translateExpression(binExpr.right, -1, rightFpReg) if (notEquals) { - code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg) + code += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=resultRegister, fpReg1 = leftFpReg, fpReg2 = rightFpReg) } else { val label = codeGen.createLabelName() - val valueReg = codeGen.vmRegisters.nextFree() - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=resultRegister, value=1) - code += IRInstruction(Opcode.FCOMP, VmDataType.FLOAT, reg1=valueReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg) - code += IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=valueReg, labelSymbol = label) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=resultRegister, value=0) + val valueReg = codeGen.registers.nextFree() + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=1) + code += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=valueReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg) + code += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=valueReg, labelSymbol = label) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=resultRegister, value=0) code += IRCodeLabel(label) } } else { @@ -390,7 +390,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { code += IRInstruction(Opcode.INV, vmDt, reg1=resultRegister) code += IRInstruction(Opcode.AND, vmDt, reg1=resultRegister, value=1) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) val opcode = if (notEquals) Opcode.SNE else Opcode.SEQ @@ -400,14 +400,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, signed: Boolean): IRCodeChunk { + private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int, signed: Boolean): IRCodeChunk { val code = IRCodeChunk(binExpr.position) if(codeGen.isOne(binExpr.right)) { code += translateExpression(binExpr.left, resultRegister, -1) val opc = if (signed) Opcode.ASR else Opcode.LSR code += IRInstruction(opc, vmDt, reg1 = resultRegister) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) val opc = if (signed) Opcode.ASRN else Opcode.LSRN @@ -416,7 +416,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorShiftRightInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { + internal fun operatorShiftRightInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) if(codeGen.isOne(operand)) { val opc = if (signed) Opcode.ASRM else Opcode.LSRM @@ -425,7 +425,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { else IRInstruction(opc, vmDt, labelSymbol = symbol) } else { - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM code += if(knownAddress!=null) @@ -436,13 +436,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): IRCodeChunk { + private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) if(codeGen.isOne(binExpr.right)){ code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.LSL, vmDt, reg1=resultRegister) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.LSLN, vmDt, reg1=resultRegister, rightResultReg) @@ -450,7 +450,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorShiftLeftInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorShiftLeftInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) if(codeGen.isOne(operand)){ code += if(knownAddress!=null) @@ -458,7 +458,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { else IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol) } else { - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.LSLNM, vmDt, reg1=operandReg, value=knownAddress) @@ -468,13 +468,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorXor(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): IRCodeChunk { + private fun operatorXor(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) if(binExpr.right is PtNumber) { code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.XOR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.XORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg) @@ -482,9 +482,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorXorInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorXorInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.XORM, vmDt, reg1=operandReg, value = knownAddress) @@ -493,13 +493,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): IRCodeChunk { + private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) if(binExpr.right is PtNumber) { code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.AND, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.ANDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg) @@ -507,9 +507,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorAndInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorAndInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.ANDM, vmDt, reg1=operandReg, value=knownAddress) @@ -518,13 +518,13 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorOr(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): IRCodeChunk { + private fun operatorOr(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) if(binExpr.right is PtNumber) { code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.OR, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.ORR, vmDt, reg1 = resultRegister, reg2 = rightResultReg) @@ -532,9 +532,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorOrInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorOrInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.ORM, vmDt, reg1=operandReg, value = knownAddress) @@ -543,10 +543,10 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): IRCodeChunk { - require(vmDt!=VmDataType.FLOAT) {"floating-point modulo not supported"} + private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int): IRCodeChunk { + require(vmDt!=IRDataType.FLOAT) {"floating-point modulo not supported"} val code = IRCodeChunk(binExpr.position) - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() if(binExpr.right is PtNumber) { code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.MOD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()) @@ -559,19 +559,19 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } private fun operatorDivide(binExpr: PtBinaryExpression, - vmDt: VmDataType, + vmDt: IRDataType, resultRegister: Int, resultFpRegister: Int, signed: Boolean): IRCodeChunk { val code = IRCodeChunk(binExpr.position) val constFactorRight = binExpr.right as? PtNumber - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { code += translateExpression(binExpr.left, -1, resultFpRegister) val factor = constFactorRight.number.toFloat() code += codeGen.divideByConstFloat(resultFpRegister, factor, binExpr.position) } else { - val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat() + val rightResultFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(binExpr.left, -1, resultFpRegister) code += translateExpression(binExpr.right, -1, rightResultFpReg) code += if(signed) @@ -585,7 +585,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val factor = constFactorRight.number.toInt() code += codeGen.divideByConst(vmDt, resultRegister, factor, signed, binExpr.position) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() if(binExpr.right is PtNumber) { code += translateExpression(binExpr.left, resultRegister, -1) code += if (signed) @@ -605,15 +605,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorDivideInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { + internal fun operatorDivideInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, signed: Boolean, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val constFactorRight = operand as? PtNumber - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { val factor = constFactorRight.number.toFloat() code += codeGen.divideByConstFloatInplace(knownAddress, symbol, factor, operand.position) } else { - val operandFpReg = codeGen.vmRegisters.nextFreeFloat() + val operandFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(operand, -1, operandFpReg) code += if(signed) { if(knownAddress!=null) @@ -633,7 +633,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val factor = constFactorRight.number.toInt() code += codeGen.divideByConstInplace(vmDt, knownAddress, symbol, factor, signed, operand.position) } else { - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(signed) { if(knownAddress!=null) @@ -652,11 +652,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { + private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) val constFactorLeft = binExpr.left as? PtNumber val constFactorRight = binExpr.right as? PtNumber - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if(constFactorLeft!=null) { code += translateExpression(binExpr.right, -1, resultFpRegister) val factor = constFactorLeft.number.toFloat() @@ -666,7 +666,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val factor = constFactorRight.number.toFloat() code += codeGen.multiplyByConstFloat(resultFpRegister, factor, constFactorRight.position) } else { - val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat() + val rightResultFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(binExpr.left, -1, resultFpRegister) code += translateExpression(binExpr.right, -1, rightResultFpReg) code += IRInstruction(Opcode.MULR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg) @@ -681,7 +681,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val factor = constFactorRight.number.toInt() code += codeGen.multiplyByConst(vmDt, resultRegister, factor, constFactorRight.position) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.MULR, vmDt, reg1 = resultRegister, reg2 = rightResultReg) @@ -690,15 +690,15 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorMultiplyInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorMultiplyInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) val constFactorRight = operand as? PtNumber - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if(constFactorRight!=null) { val factor = constFactorRight.number.toFloat() code += codeGen.multiplyByConstFloatInplace(knownAddress, symbol, factor, constFactorRight.position) } else { - val operandFpReg = codeGen.vmRegisters.nextFreeFloat() + val operandFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(operand, -1, operandFpReg) code += if(knownAddress!=null) IRInstruction(Opcode.MULM, vmDt, fpReg1 = operandFpReg, value = knownAddress) @@ -710,7 +710,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val factor = constFactorRight.number.toInt() code += codeGen.multiplyByConstInplace(vmDt, knownAddress, symbol, factor, constFactorRight.position) } else { - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.MULM, vmDt, reg1=operandReg, value = knownAddress) @@ -721,9 +721,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { + private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if((binExpr.right as? PtNumber)?.number==1.0) { code += translateExpression(binExpr.left, -1, resultFpRegister) code += IRInstruction(Opcode.DEC, vmDt, fpReg1 = resultFpRegister) @@ -733,7 +733,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { code += translateExpression(binExpr.left, -1, resultFpRegister) code += IRInstruction(Opcode.SUB, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()) } else { - val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat() + val rightResultFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(binExpr.left, -1, resultFpRegister) code += translateExpression(binExpr.right, -1, rightResultFpReg) code += IRInstruction(Opcode.SUBR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg) @@ -749,7 +749,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.SUB, vmDt, reg1 = resultRegister, value = (binExpr.right as PtNumber).number.toInt()) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.SUBR, vmDt, reg1 = resultRegister, reg2 = rightResultReg) @@ -759,9 +759,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorMinusInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorMinusInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if((operand as? PtNumber)?.number==1.0) { code += if(knownAddress!=null) IRInstruction(Opcode.DECM, vmDt, value=knownAddress) @@ -769,7 +769,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol) } else { - val operandFpReg = codeGen.vmRegisters.nextFreeFloat() + val operandFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(operand, -1, operandFpReg) code += if(knownAddress!=null) IRInstruction(Opcode.SUBM, vmDt, fpReg1=operandFpReg, value=knownAddress) @@ -784,7 +784,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol) } else { - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.SUBM, vmDt, reg1=operandReg, value = knownAddress) @@ -795,9 +795,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { + private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: IRDataType, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { val code = IRCodeChunk(binExpr.position) - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if((binExpr.left as? PtNumber)?.number==1.0) { code += translateExpression(binExpr.right, -1, resultFpRegister) code += IRInstruction(Opcode.INC, vmDt, fpReg1=resultFpRegister) @@ -811,7 +811,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { code += translateExpression(binExpr.left, -1, resultFpRegister) code += IRInstruction(Opcode.ADD, vmDt, fpReg1 = resultFpRegister, fpValue = (binExpr.right as PtNumber).number.toFloat()) } else { - val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat() + val rightResultFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(binExpr.left, -1, resultFpRegister) code += translateExpression(binExpr.right, -1, rightResultFpReg) code += IRInstruction(Opcode.ADDR, vmDt, fpReg1 = resultFpRegister, fpReg2 = rightResultFpReg) @@ -831,7 +831,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { code += translateExpression(binExpr.left, resultRegister, -1) code += IRInstruction(Opcode.ADD, vmDt, reg1 = resultRegister, value=(binExpr.right as PtNumber).number.toInt()) } else { - val rightResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.registers.nextFree() code += translateExpression(binExpr.left, resultRegister, -1) code += translateExpression(binExpr.right, rightResultReg, -1) code += IRInstruction(Opcode.ADDR, vmDt, reg1 = resultRegister, reg2 = rightResultReg) @@ -841,9 +841,9 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { return code } - internal fun operatorPlusInplace(knownAddress: Int?, symbol: String?, vmDt: VmDataType, operand: PtExpression): IRCodeChunk { + internal fun operatorPlusInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): IRCodeChunk { val code = IRCodeChunk(operand.position) - if(vmDt==VmDataType.FLOAT) { + if(vmDt==IRDataType.FLOAT) { if((operand as? PtNumber)?.number==1.0) { code += if(knownAddress!=null) IRInstruction(Opcode.INCM, vmDt, value = knownAddress) @@ -851,7 +851,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol) } else { - val operandFpReg = codeGen.vmRegisters.nextFreeFloat() + val operandFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(operand, -1, operandFpReg) code += if(knownAddress!=null) IRInstruction(Opcode.ADDM, vmDt, fpReg1=operandFpReg, value = knownAddress) @@ -866,7 +866,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { IRInstruction(Opcode.INCM, vmDt, labelSymbol = symbol) } else { - val operandReg = codeGen.vmRegisters.nextFree() + val operandReg = codeGen.registers.nextFree() code += translateExpression(operand, operandReg, -1) code += if(knownAddress!=null) IRInstruction(Opcode.ADDM, vmDt, reg1=operandReg, value=knownAddress) @@ -882,17 +882,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { is StSub -> { val code = IRCodeChunk(fcall.position) for ((arg, parameter) in fcall.args.zip(callTarget.parameters)) { - val paramDt = codeGen.vmType(parameter.type) + val paramDt = codeGen.irType(parameter.type) val symbol = (fcall.functionName + parameter.name).joinToString(".") if(codeGen.isZero(arg)) { code += IRInstruction(Opcode.STOREZM, paramDt, labelSymbol = symbol) } else { - if (paramDt == VmDataType.FLOAT) { - val argFpReg = codeGen.vmRegisters.nextFreeFloat() + if (paramDt == IRDataType.FLOAT) { + val argFpReg = codeGen.registers.nextFreeFloat() code += translateExpression(arg, -1, argFpReg) code += IRInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, labelSymbol = symbol) } else { - val argReg = codeGen.vmRegisters.nextFree() + val argReg = codeGen.registers.nextFree() code += translateExpression(arg, argReg, -1) code += IRInstruction(Opcode.STOREM, paramDt, reg1 = argReg, labelSymbol = symbol) } @@ -902,12 +902,12 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { if(fcall.type==DataType.FLOAT) { if (!fcall.void && resultFpRegister != 0) { // Call convention: result value is in fr0, so put it in the required register instead. - code += IRInstruction(Opcode.LOADR, VmDataType.FLOAT, fpReg1 = resultFpRegister, fpReg2 = 0) + code += IRInstruction(Opcode.LOADR, IRDataType.FLOAT, fpReg1 = resultFpRegister, fpReg2 = 0) } } else { if (!fcall.void && resultRegister != 0) { // Call convention: result value is in r0, so put it in the required register instead. - code += IRInstruction(Opcode.LOADR, codeGen.vmType(fcall.type), reg1 = resultRegister, reg2 = 0) + code += IRInstruction(Opcode.LOADR, codeGen.irType(fcall.type), reg1 = resultRegister, reg2 = 0) } } return code @@ -915,14 +915,14 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { is StRomSub -> { val code = IRCodeChunk(fcall.position) for ((arg, parameter) in fcall.args.zip(callTarget.parameters)) { - val paramDt = codeGen.vmType(parameter.type) + val paramDt = codeGen.irType(parameter.type) val paramRegStr = if(parameter.register.registerOrPair!=null) parameter.register.registerOrPair.toString() else parameter.register.statusflag.toString() if(codeGen.isZero(arg)) { code += IRInstruction(Opcode.STOREZCPU, paramDt, labelSymbol = paramRegStr) } else { - if (paramDt == VmDataType.FLOAT) + if (paramDt == IRDataType.FLOAT) throw AssemblyError("doesn't support float register argument in asm romsub") - val argReg = codeGen.vmRegisters.nextFree() + val argReg = codeGen.registers.nextFree() code += translateExpression(arg, argReg, -1) code += IRInstruction(Opcode.STORECPU, paramDt, reg1 = argReg, labelSymbol = paramRegStr) } @@ -935,7 +935,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { throw AssemblyError("doesn't support float register result in asm romsub") val returns = callTarget.returns.single() val regStr = if(returns.registerOrPair!=null) returns.registerOrPair.toString() else returns.statusflag.toString() - code += IRInstruction(Opcode.LOADCPU, codeGen.vmType(fcall.type), reg1=resultRegister, labelSymbol = regStr) + code += IRInstruction(Opcode.LOADCPU, codeGen.irType(fcall.type), reg1=resultRegister, labelSymbol = regStr) } return code } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 5503c2e18..c6ae19ef5 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -20,7 +20,7 @@ class IRCodeGen( private val expressionEval = ExpressionGen(this) private val builtinFuncGen = BuiltinFuncGen(this, expressionEval) private val assignmentGen = AssignmentGen(this, expressionEval) - internal val vmRegisters = RegisterPool() + internal val registers = RegisterPool() fun generate(): IRProgram { flattenLabelNames() @@ -28,6 +28,9 @@ class IRCodeGen( val irProg = IRProgram(program.name, IRSymbolTable(symbolTable), options, program.encoding) + if(options.evalStackBaseAddress!=null) + throw AssemblyError("IR doesn't use eval-stack") + if(!options.dontReinitGlobals) { // collect global variables initializers program.allBlocks().forEach { @@ -37,14 +40,10 @@ class IRCodeGen( } } - if(options.symbolDefs.isNotEmpty()) - throw AssemblyError("virtual target doesn't support symbols defined on the commandline") - if(options.evalStackBaseAddress!=null) - throw AssemblyError("virtual target doesn't use eval-stack") + irProg.addAsmSymbols(options.symbolDefs) - for (block in program.allBlocks()) { + for (block in program.allBlocks()) irProg.addBlock(translate(block)) - } replaceMemoryMappedVars(irProg) @@ -280,8 +279,8 @@ class IRCodeGen( BranchCondition.NE, BranchCondition.NZ -> IRInstruction(Opcode.BSTEQ, labelSymbol = elseLabel) BranchCondition.MI, BranchCondition.NEG -> IRInstruction(Opcode.BSTPOS, labelSymbol = elseLabel) BranchCondition.PL, BranchCondition.POS -> IRInstruction(Opcode.BSTNEG, labelSymbol = elseLabel) - BranchCondition.VC, - BranchCondition.VS -> throw AssemblyError("conditional branch ${branch.condition} not supported in vm target due to lack of cpu V flag ${branch.position}") + BranchCondition.VC -> IRInstruction(Opcode.BSTVC, labelSymbol = elseLabel) + BranchCondition.VS -> IRInstruction(Opcode.BSTVS, labelSymbol = elseLabel) } code += translateNode(branch.trueScope) if(branch.falseScope.children.isNotEmpty()) { @@ -300,9 +299,9 @@ class IRCodeGen( val code = IRCodeChunk(whenStmt.position) if(whenStmt.choices.children.isEmpty()) return code - val valueReg = vmRegisters.nextFree() - val choiceReg = vmRegisters.nextFree() - val valueDt = vmType(whenStmt.value.type) + val valueReg = registers.nextFree() + val choiceReg = registers.nextFree() + val valueDt = irType(whenStmt.value.type) code += expressionEval.translateExpression(whenStmt.value, valueReg, -1) val choices = whenStmt.choices.children.map {it as PtWhenChoice } val endLabel = createLabelName() @@ -352,19 +351,19 @@ class IRCodeGen( val symbol = iterable.targetName.joinToString(".") val iterableVar = symbolTable.lookup(iterable.targetName) as StStaticVariable val loopvarSymbol = loopvar.scopedName.joinToString(".") - val indexReg = vmRegisters.nextFree() - val tmpReg = vmRegisters.nextFree() + val indexReg = registers.nextFree() + val tmpReg = registers.nextFree() val loopLabel = createLabelName() val endLabel = createLabelName() if(iterableVar.dt==DataType.STR) { // iterate over a zero-terminated string - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0) code += IRCodeLabel(loopLabel) - code += IRInstruction(Opcode.LOADX, VmDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol) - code += IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel) - code += IRInstruction(Opcode.STOREM, VmDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol) + code += IRInstruction(Opcode.LOADX, IRDataType.BYTE, reg1=tmpReg, reg2=indexReg, labelSymbol = symbol) + code += IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=tmpReg, labelSymbol = endLabel) + code += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1=tmpReg, labelSymbol = loopvarSymbol) code += translateNode(forLoop.statements) - code += IRInstruction(Opcode.INC, VmDataType.BYTE, reg1=indexReg) + code += IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=indexReg) code += IRInstruction(Opcode.JUMP, labelSymbol = loopLabel) code += IRCodeLabel(endLabel) } else { @@ -373,23 +372,23 @@ class IRCodeGen( val elementSize = program.memsizer.memorySize(elementDt) val lengthBytes = iterableVar.length!! * elementSize if(lengthBytes<256) { - val lengthReg = vmRegisters.nextFree() - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=lengthReg, value=lengthBytes) + val lengthReg = registers.nextFree() + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=lengthReg, value=lengthBytes) code += IRCodeLabel(loopLabel) - code += IRInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol) - code += IRInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol) + code += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol) + code += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol) code += translateNode(forLoop.statements) - code += addConstReg(VmDataType.BYTE, indexReg, elementSize, iterable.position) - code += IRInstruction(Opcode.BNE, VmDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel) + code += addConstReg(IRDataType.BYTE, indexReg, elementSize, iterable.position) + code += IRInstruction(Opcode.BNE, IRDataType.BYTE, reg1=indexReg, reg2=lengthReg, labelSymbol = loopLabel) } else if(lengthBytes==256) { - code += IRInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=indexReg, value=0) + code += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1=indexReg, value=0) code += IRCodeLabel(loopLabel) - code += IRInstruction(Opcode.LOADX, vmType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol) - code += IRInstruction(Opcode.STOREM, vmType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol) + code += IRInstruction(Opcode.LOADX, irType(elementDt), reg1=tmpReg, reg2=indexReg, labelSymbol=symbol) + code += IRInstruction(Opcode.STOREM, irType(elementDt), reg1=tmpReg, labelSymbol = loopvarSymbol) code += translateNode(forLoop.statements) - code += addConstReg(VmDataType.BYTE, indexReg, elementSize, iterable.position) - code += IRInstruction(Opcode.BNZ, VmDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel) + code += addConstReg(IRDataType.BYTE, indexReg, elementSize, iterable.position) + code += IRInstruction(Opcode.BNZ, IRDataType.BYTE, reg1=indexReg, labelSymbol = loopLabel) } else { throw AssemblyError("iterator length should never exceed 256") } @@ -405,10 +404,10 @@ class IRCodeGen( val step = iterable.step.number.toInt() if (step==0) throw AssemblyError("step 0") - val indexReg = vmRegisters.nextFree() - val endvalueReg = vmRegisters.nextFree() + val indexReg = registers.nextFree() + val endvalueReg = registers.nextFree() val loopvarSymbol = loopvar.scopedName.joinToString(".") - val loopvarDt = vmType(loopvar.dt) + val loopvarDt = irType(loopvar.dt) val loopLabel = createLabelName() val code = IRCodeChunk(forLoop.position) @@ -427,8 +426,8 @@ class IRCodeGen( private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StStaticVariable): IRCodeChunk { val loopLabel = createLabelName() val loopvarSymbol = loopvar.scopedName.joinToString(".") - val indexReg = vmRegisters.nextFree() - val loopvarDt = vmType(loopvar.dt) + val indexReg = registers.nextFree() + val loopvarDt = irType(loopvar.dt) val iterable = forLoop.iterable as PtRange val step = iterable.step.number.toInt() val rangeStart = (iterable.from as PtNumber).number.toInt() @@ -437,11 +436,11 @@ class IRCodeGen( throw AssemblyError("step 0") if(step>0 && rangeEndUntypedrangeStart) throw AssemblyError("empty range") - val rangeEndWrapped = if(loopvarDt==VmDataType.BYTE) rangeEndUntyped and 255 else rangeEndUntyped and 65535 + val rangeEndWrapped = if(loopvarDt==IRDataType.BYTE) rangeEndUntyped and 255 else rangeEndUntyped and 65535 val code = IRCodeChunk(forLoop.position) val endvalueReg: Int if(rangeEndWrapped!=0) { - endvalueReg = vmRegisters.nextFree() + endvalueReg = registers.nextFree() code += IRInstruction(Opcode.LOAD, loopvarDt, reg1 = endvalueReg, value = rangeEndWrapped) } else { endvalueReg = -1 // not used @@ -460,7 +459,7 @@ class IRCodeGen( return code } - private fun addConstReg(dt: VmDataType, reg: Int, value: Int, position: Position): IRCodeChunk { + private fun addConstReg(dt: IRDataType, reg: Int, value: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) when(value) { 0 -> { /* do nothing */ } @@ -489,7 +488,7 @@ class IRCodeGen( return code } - private fun addConstMem(dt: VmDataType, knownAddress: UInt?, symbol: String?, value: Int, position: Position): IRCodeChunk { + private fun addConstMem(dt: IRDataType, knownAddress: UInt?, symbol: String?, value: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) when(value) { 0 -> { /* do nothing */ } @@ -524,7 +523,7 @@ class IRCodeGen( } } else -> { - val valueReg = vmRegisters.nextFree() + val valueReg = registers.nextFree() if(value>0) { code += IRInstruction(Opcode.LOAD, dt, reg1=valueReg, value=value) code += if(knownAddress!=null) @@ -549,9 +548,9 @@ class IRCodeGen( if(factor==1f) return code code += if(factor==0f) { - IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f) + IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f) } else { - IRInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor) + IRInstruction(Opcode.MUL, IRDataType.FLOAT, fpReg1 = fpReg, fpValue=factor) } return code } @@ -562,23 +561,23 @@ class IRCodeGen( return code if(factor==0f) { code += if(knownAddress!=null) - IRInstruction(Opcode.STOREZM, VmDataType.FLOAT, value = knownAddress) + IRInstruction(Opcode.STOREZM, IRDataType.FLOAT, value = knownAddress) else - IRInstruction(Opcode.STOREZM, VmDataType.FLOAT, labelSymbol = symbol) + IRInstruction(Opcode.STOREZM, IRDataType.FLOAT, labelSymbol = symbol) } else { - val factorReg = vmRegisters.nextFreeFloat() - code += IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor) + val factorReg = registers.nextFreeFloat() + code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, fpValue = factor) code += if(knownAddress!=null) - IRInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, value = knownAddress) + IRInstruction(Opcode.MULM, IRDataType.FLOAT, fpReg1 = factorReg, value = knownAddress) else - IRInstruction(Opcode.MULM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol) + IRInstruction(Opcode.MULM, IRDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol) } return code } internal val powersOfTwo = (0..16).map { 2.0.pow(it.toDouble()).toInt() } - internal fun multiplyByConst(dt: VmDataType, reg: Int, factor: Int, position: Position): IRCodeChunk { + internal fun multiplyByConst(dt: IRDataType, reg: Int, factor: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1) return code @@ -589,7 +588,7 @@ class IRCodeGen( } else if(pow2>=1) { // just shift multiple bits - val pow2reg = vmRegisters.nextFree() + val pow2reg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2) code += IRInstruction(Opcode.LSLN, dt, reg1=reg, reg2=pow2reg) } else { @@ -602,7 +601,7 @@ class IRCodeGen( return code } - internal fun multiplyByConstInplace(dt: VmDataType, knownAddress: Int?, symbol: String?, factor: Int, position: Position): IRCodeChunk { + internal fun multiplyByConstInplace(dt: IRDataType, knownAddress: Int?, symbol: String?, factor: Int, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1) return code @@ -616,7 +615,7 @@ class IRCodeGen( } else if(pow2>=1) { // just shift multiple bits - val pow2reg = vmRegisters.nextFree() + val pow2reg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2) code += if(knownAddress!=null) IRInstruction(Opcode.LSLNM, dt, reg1=pow2reg, value=knownAddress) @@ -630,7 +629,7 @@ class IRCodeGen( IRInstruction(Opcode.STOREZM, dt, labelSymbol = symbol) } else { - val factorReg = vmRegisters.nextFree() + val factorReg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, value = factor) code += if(knownAddress!=null) IRInstruction(Opcode.MULM, dt, reg1=factorReg, value = knownAddress) @@ -646,9 +645,9 @@ class IRCodeGen( if(factor==1f) return code code += if(factor==0f) { - IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE) + IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = fpReg, fpValue = Float.MAX_VALUE) } else { - IRInstruction(Opcode.DIVS, VmDataType.FLOAT, fpReg1 = fpReg, fpValue=factor) + IRInstruction(Opcode.DIVS, IRDataType.FLOAT, fpReg1 = fpReg, fpValue=factor) } return code } @@ -658,24 +657,24 @@ class IRCodeGen( if(factor==1f) return code if(factor==0f) { - val maxvalueReg = vmRegisters.nextFreeFloat() - code += IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = maxvalueReg, fpValue = Float.MAX_VALUE) + val maxvalueReg = registers.nextFreeFloat() + code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = maxvalueReg, fpValue = Float.MAX_VALUE) code += if(knownAddress!=null) - IRInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, value=knownAddress) + IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, value=knownAddress) else - IRInstruction(Opcode.STOREM, VmDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol) + IRInstruction(Opcode.STOREM, IRDataType.FLOAT, fpReg1 = maxvalueReg, labelSymbol = symbol) } else { - val factorReg = vmRegisters.nextFreeFloat() - code += IRInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1=factorReg, fpValue = factor) + val factorReg = registers.nextFreeFloat() + code += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1=factorReg, fpValue = factor) code += if(knownAddress!=null) - IRInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, value=knownAddress) + IRInstruction(Opcode.DIVSM, IRDataType.FLOAT, fpReg1 = factorReg, value=knownAddress) else - IRInstruction(Opcode.DIVSM, VmDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol) + IRInstruction(Opcode.DIVSM, IRDataType.FLOAT, fpReg1 = factorReg, labelSymbol = symbol) } return code } - internal fun divideByConst(dt: VmDataType, reg: Int, factor: Int, signed: Boolean, position: Position): IRCodeChunk { + internal fun divideByConst(dt: IRDataType, reg: Int, factor: Int, signed: Boolean, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1) return code @@ -685,7 +684,7 @@ class IRCodeGen( } else if(pow2>=1 &&!signed) { // just shift multiple bits - val pow2reg = vmRegisters.nextFree() + val pow2reg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2) code += if(signed) IRInstruction(Opcode.ASRN, dt, reg1=reg, reg2=pow2reg) @@ -704,7 +703,7 @@ class IRCodeGen( return code } - internal fun divideByConstInplace(dt: VmDataType, knownAddress: Int?, symbol: String?, factor: Int, signed: Boolean, position: Position): IRCodeChunk { + internal fun divideByConstInplace(dt: IRDataType, knownAddress: Int?, symbol: String?, factor: Int, signed: Boolean, position: Position): IRCodeChunk { val code = IRCodeChunk(position) if(factor==1) return code @@ -718,7 +717,7 @@ class IRCodeGen( } else if(pow2>=1 && !signed) { // just shift multiple bits - val pow2reg = vmRegisters.nextFree() + val pow2reg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=pow2reg, value=pow2) code += if(signed) { if(knownAddress!=null) @@ -734,7 +733,7 @@ class IRCodeGen( } } else { if (factor == 0) { - val reg = vmRegisters.nextFree() + val reg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=reg, value=0xffff) code += if(knownAddress!=null) IRInstruction(Opcode.STOREM, dt, reg1=reg, value=knownAddress) @@ -742,7 +741,7 @@ class IRCodeGen( IRInstruction(Opcode.STOREM, dt, reg1=reg, labelSymbol = symbol) } else { - val factorReg = vmRegisters.nextFree() + val factorReg = registers.nextFree() code += IRInstruction(Opcode.LOAD, dt, reg1=factorReg, value= factor) code += if(signed) { if(knownAddress!=null) @@ -766,7 +765,7 @@ class IRCodeGen( throw AssemblyError("if condition should only be a binary comparison expression") val signed = ifElse.condition.left.type in arrayOf(DataType.BYTE, DataType.WORD, DataType.FLOAT) - val vmDt = vmType(ifElse.condition.left.type) + val irDt = irType(ifElse.condition.left.type) val code = IRCodeChunk(ifElse.position) fun translateNonZeroComparison(): IRCodeChunk { @@ -780,15 +779,15 @@ class IRCodeGen( else -> throw AssemblyError("invalid comparison operator") } - val leftReg = vmRegisters.nextFree() - val rightReg = vmRegisters.nextFree() + val leftReg = registers.nextFree() + val rightReg = registers.nextFree() code += expressionEval.translateExpression(ifElse.condition.left, leftReg, -1) code += expressionEval.translateExpression(ifElse.condition.right, rightReg, -1) if(ifElse.elseScope.children.isNotEmpty()) { // if and else parts val elseLabel = createLabelName() val afterIfLabel = createLabelName() - code += IRInstruction(elseBranch, vmDt, reg1=leftReg, reg2=rightReg, labelSymbol = elseLabel) + code += IRInstruction(elseBranch, irDt, reg1=leftReg, reg2=rightReg, labelSymbol = elseLabel) code += translateNode(ifElse.ifScope) code += IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel) code += IRCodeLabel(elseLabel) @@ -797,7 +796,7 @@ class IRCodeGen( } else { // only if part val afterIfLabel = createLabelName() - code += IRInstruction(elseBranch, vmDt, reg1=leftReg, reg2=rightReg, labelSymbol = afterIfLabel) + code += IRInstruction(elseBranch, irDt, reg1=leftReg, reg2=rightReg, labelSymbol = afterIfLabel) code += translateNode(ifElse.ifScope) code += IRCodeLabel(afterIfLabel) } @@ -806,13 +805,13 @@ class IRCodeGen( fun translateZeroComparison(): IRCodeChunk { fun equalOrNotEqualZero(elseBranch: Opcode): IRCodeChunk { - val leftReg = vmRegisters.nextFree() + val leftReg = registers.nextFree() code += expressionEval.translateExpression(ifElse.condition.left, leftReg, -1) if(ifElse.elseScope.children.isNotEmpty()) { // if and else parts val elseLabel = createLabelName() val afterIfLabel = createLabelName() - code += IRInstruction(elseBranch, vmDt, reg1=leftReg, labelSymbol = elseLabel) + code += IRInstruction(elseBranch, irDt, reg1=leftReg, labelSymbol = elseLabel) code += translateNode(ifElse.ifScope) code += IRInstruction(Opcode.JUMP, labelSymbol = afterIfLabel) code += IRCodeLabel(elseLabel) @@ -821,7 +820,7 @@ class IRCodeGen( } else { // only if part val afterIfLabel = createLabelName() - code += IRInstruction(elseBranch, vmDt, reg1=leftReg, labelSymbol = afterIfLabel) + code += IRInstruction(elseBranch, irDt, reg1=leftReg, labelSymbol = afterIfLabel) code += translateNode(ifElse.ifScope) code += IRCodeLabel(afterIfLabel) } @@ -868,20 +867,20 @@ class IRCodeGen( val ident = postIncrDecr.target.identifier val memory = postIncrDecr.target.memory val array = postIncrDecr.target.array - val vmDt = vmType(postIncrDecr.target.type) + val irDt = irType(postIncrDecr.target.type) if(ident!=null) { - code += IRInstruction(operationMem, vmDt, labelSymbol = ident.targetName.joinToString(".")) + code += IRInstruction(operationMem, irDt, labelSymbol = ident.targetName.joinToString(".")) } else if(memory!=null) { if(memory.address is PtNumber) { val address = (memory.address as PtNumber).number.toInt() - code += IRInstruction(operationMem, vmDt, value = address) + code += IRInstruction(operationMem, irDt, value = address) } else { - val incReg = vmRegisters.nextFree() - val addressReg = vmRegisters.nextFree() + val incReg = registers.nextFree() + val addressReg = registers.nextFree() code += expressionEval.translateExpression(memory.address, addressReg, -1) - code += IRInstruction(Opcode.LOADI, vmDt, reg1 = incReg, reg2 = addressReg) - code += IRInstruction(operationRegister, vmDt, reg1 = incReg) - code += IRInstruction(Opcode.STOREI, vmDt, reg1 = incReg, reg2 = addressReg) + code += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = addressReg) + code += IRInstruction(operationRegister, irDt, reg1 = incReg) + code += IRInstruction(Opcode.STOREI, irDt, reg1 = incReg, reg2 = addressReg) } } else if (array!=null) { val variable = array.variable.targetName.joinToString(".") @@ -889,14 +888,14 @@ class IRCodeGen( val fixedIndex = constIntValue(array.index) if(fixedIndex!=null) { val offset = fixedIndex*itemsize - code += IRInstruction(operationMem, vmDt, labelSymbol="$variable+$offset") + code += IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset") } else { - val incReg = vmRegisters.nextFree() - val indexReg = vmRegisters.nextFree() + val incReg = registers.nextFree() + val indexReg = registers.nextFree() code += expressionEval.translateExpression(array.index, indexReg, -1) - code += IRInstruction(Opcode.LOADX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable) - code += IRInstruction(operationRegister, vmDt, reg1=incReg) - code += IRInstruction(Opcode.STOREX, vmDt, reg1=incReg, reg2=indexReg, labelSymbol=variable) + code += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable) + code += IRInstruction(operationRegister, irDt, reg1=incReg) + code += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable) } } else throw AssemblyError("weird assigntarget") @@ -917,28 +916,30 @@ class IRCodeGen( val repeatLabel = createLabelName() val skipRepeatLabel = createLabelName() val code = IRCodeChunk(repeat.position) - val counterReg = vmRegisters.nextFree() - val vmDt = vmType(repeat.count.type) + val counterReg = registers.nextFree() + val irDt = irType(repeat.count.type) code += expressionEval.translateExpression(repeat.count, counterReg, -1) - code += IRInstruction(Opcode.BZ, vmDt, reg1=counterReg, labelSymbol = skipRepeatLabel) + code += IRInstruction(Opcode.BZ, irDt, reg1=counterReg, labelSymbol = skipRepeatLabel) code += IRCodeLabel(repeatLabel) code += translateNode(repeat.statements) - code += IRInstruction(Opcode.DEC, vmDt, reg1=counterReg) - code += IRInstruction(Opcode.BNZ, vmDt, reg1=counterReg, labelSymbol = repeatLabel) + code += IRInstruction(Opcode.DEC, irDt, reg1=counterReg) + code += IRInstruction(Opcode.BNZ, irDt, reg1=counterReg, labelSymbol = repeatLabel) code += IRCodeLabel(skipRepeatLabel) return code } private fun translate(jump: PtJump): IRCodeChunk { val code = IRCodeChunk(jump.position) - if(jump.address!=null) - throw AssemblyError("cannot jump to memory location in the vm target") - code += if(jump.generatedLabel!=null) - IRInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!) - else if(jump.identifier!=null) - IRInstruction(Opcode.JUMP, labelSymbol = jump.identifier!!.targetName.joinToString(".")) - else - throw AssemblyError("weird jump") + code += if(jump.address!=null) { + IRInstruction(Opcode.JUMPA, value = jump.address!!.toInt()) + } else { + if (jump.generatedLabel != null) + IRInstruction(Opcode.JUMP, labelSymbol = jump.generatedLabel!!) + else if (jump.identifier != null) + IRInstruction(Opcode.JUMP, labelSymbol = jump.identifier!!.targetName.joinToString(".")) + else + throw AssemblyError("weird jump") + } return code } @@ -963,24 +964,24 @@ class IRCodeGen( } private fun translate(block: PtBlock): IRBlock { - val vmblock = IRBlock(block.name, block.address, translate(block.alignment), block.position) // no use for other attributes yet? + val irBlock = IRBlock(block.name, block.address, translate(block.alignment), block.position) // no use for other attributes yet? for (child in block.children) { when(child) { is PtNop -> { /* nothing */ } is PtAssignment -> { /* global variable initialization is done elsewhere */ } is PtScopeVarsDecls -> { /* vars should be looked up via symbol table */ } is PtSub -> { - val vmsub = IRSubroutine(child.name, translate(child.parameters), child.returntype, child.position) + val sub = IRSubroutine(child.name, translate(child.parameters), child.returntype, child.position) for (subchild in child.children) { val translated = translateNode(subchild) if(translated.isNotEmpty()) - vmsub += translated + sub += translated } - vmblock += vmsub + irBlock += sub } is PtAsmSub -> { val assemblyChild = if(child.children.isEmpty()) null else (child.children.single() as PtInlineAssembly) - vmblock += IRAsmSubroutine( + irBlock += IRAsmSubroutine( child.name, child.position, child.address, child.clobbers, child.parameters.map { Pair(it.first.type, it.second) }, // note: the name of the asmsub param is not used anymore. @@ -990,12 +991,12 @@ class IRCodeGen( ) } is PtInlineAssembly -> { - vmblock += IRInlineAsmChunk(child.assembly, child.isIR, child.position) + irBlock += IRInlineAsmChunk(child.assembly, child.isIR, child.position) } - else -> TODO("BLOCK HAS WEIRD CHILD NODE $child") + else -> TODO("weird child node $child") } } - return vmblock + return irBlock } private fun translate(parameters: List) = @@ -1014,16 +1015,16 @@ class IRCodeGen( } - internal fun vmType(type: DataType): VmDataType { + internal fun irType(type: DataType): IRDataType { return when(type) { DataType.BOOL, DataType.UBYTE, - DataType.BYTE -> VmDataType.BYTE + DataType.BYTE -> IRDataType.BYTE DataType.UWORD, - DataType.WORD -> VmDataType.WORD - DataType.FLOAT -> VmDataType.FLOAT - in PassByReferenceDatatypes -> VmDataType.WORD - else -> throw AssemblyError("no vm datatype for $type") + DataType.WORD -> IRDataType.WORD + DataType.FLOAT -> IRDataType.FLOAT + in PassByReferenceDatatypes -> IRDataType.WORD + else -> throw AssemblyError("no IR datatype for $type") } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt index 8340304a8..1e085af88 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt @@ -111,12 +111,11 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) { } private fun removeWeirdBranches(chunk: IRCodeChunk, indexedInstructions: List>): Boolean { - // jump/branch to label immediately below var changed = false indexedInstructions.reversed().forEach { (idx, ins) -> val labelSymbol = ins.labelSymbol if(ins.opcode== Opcode.JUMP && labelSymbol!=null) { - // if jumping to label immediately following this + // remove jump/branch to label immediately below if(idx < chunk.lines.size-1) { val label = chunk.lines[idx+1] as? IRCodeLabel if(label?.name == labelSymbol) { @@ -125,6 +124,14 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) { } } } + // remove useless RETURN + if(ins.opcode == Opcode.RETURN && idx>0) { + val previous = chunk.lines[idx-1] as? IRInstruction + if(previous?.opcode in setOf(Opcode.JUMP, Opcode.JUMPA, Opcode.RETURN)) { + chunk.lines.removeAt(idx) + changed = true + } + } } return changed } @@ -157,10 +164,10 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) { if (ins.value == 0) { chunk.lines[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = 0) changed = true - } else if (ins.value == 255 && ins.type == VmDataType.BYTE) { + } else if (ins.value == 255 && ins.type == IRDataType.BYTE) { chunk.lines.removeAt(idx) changed = true - } else if (ins.value == 65535 && ins.type == VmDataType.WORD) { + } else if (ins.value == 65535 && ins.type == IRDataType.WORD) { chunk.lines.removeAt(idx) changed = true } @@ -169,7 +176,7 @@ internal class IRPeepholeOptimizer(private val irprog: IRProgram) { if (ins.value == 0) { chunk.lines.removeAt(idx) changed = true - } else if ((ins.value == 255 && ins.type == VmDataType.BYTE) || (ins.value == 65535 && ins.type == VmDataType.WORD)) { + } else if ((ins.value == 255 && ins.type == IRDataType.BYTE) || (ins.value == 65535 && ins.type == IRDataType.WORD)) { chunk.lines[idx] = IRInstruction(Opcode.LOAD, ins.type, reg1 = ins.reg1, value = ins.value) changed = true } diff --git a/codeGenIntermediate/test/TestIRPeepholeOpt.kt b/codeGenIntermediate/test/TestIRPeepholeOpt.kt index 80e43d1d0..ca50f1561 100644 --- a/codeGenIntermediate/test/TestIRPeepholeOpt.kt +++ b/codeGenIntermediate/test/TestIRPeepholeOpt.kt @@ -52,7 +52,7 @@ class TestIRPeepholeOpt: FunSpec({ IRInstruction(Opcode.NOP), // removed IRCodeLabel("label2"), IRInstruction(Opcode.JUMP, labelSymbol = "label3"), - IRInstruction(Opcode.INC, VmDataType.BYTE, reg1=1), + IRInstruction(Opcode.INC, IRDataType.BYTE, reg1=1), IRCodeLabel("label3") )) irProg.lines().size shouldBe 8 @@ -86,10 +86,10 @@ class TestIRPeepholeOpt: FunSpec({ test("push followed by pop") { val irProg = makeIRProgram(listOf( - IRInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=42), - IRInstruction(Opcode.POP, VmDataType.BYTE, reg1=42), - IRInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=99), - IRInstruction(Opcode.POP, VmDataType.BYTE, reg1=222) + IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=42), + IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=42), + IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=99), + IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=222) )) irProg.lines().size shouldBe 4 val opt = IRPeepholeOptimizer(irProg) @@ -103,16 +103,16 @@ class TestIRPeepholeOpt: FunSpec({ test("remove useless div/mul, add/sub") { val irProg = makeIRProgram(listOf( - IRInstruction(Opcode.DIV, VmDataType.BYTE, reg1=42, value = 1), - IRInstruction(Opcode.DIVS, VmDataType.BYTE, reg1=42, value = 1), - IRInstruction(Opcode.MUL, VmDataType.BYTE, reg1=42, value = 1), - IRInstruction(Opcode.MOD, VmDataType.BYTE, reg1=42, value = 1), - IRInstruction(Opcode.DIV, VmDataType.BYTE, reg1=42, value = 2), - IRInstruction(Opcode.DIVS, VmDataType.BYTE, reg1=42, value = 2), - IRInstruction(Opcode.MUL, VmDataType.BYTE, reg1=42, value = 2), - IRInstruction(Opcode.MOD, VmDataType.BYTE, reg1=42, value = 2), - IRInstruction(Opcode.ADD, VmDataType.BYTE, reg1=42, value = 0), - IRInstruction(Opcode.SUB, VmDataType.BYTE, reg1=42, value = 0) + IRInstruction(Opcode.DIV, IRDataType.BYTE, reg1=42, value = 1), + IRInstruction(Opcode.DIVS, IRDataType.BYTE, reg1=42, value = 1), + IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=42, value = 1), + IRInstruction(Opcode.MOD, IRDataType.BYTE, reg1=42, value = 1), + IRInstruction(Opcode.DIV, IRDataType.BYTE, reg1=42, value = 2), + IRInstruction(Opcode.DIVS, IRDataType.BYTE, reg1=42, value = 2), + IRInstruction(Opcode.MUL, IRDataType.BYTE, reg1=42, value = 2), + IRInstruction(Opcode.MOD, IRDataType.BYTE, reg1=42, value = 2), + IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, value = 0), + IRInstruction(Opcode.SUB, IRDataType.BYTE, reg1=42, value = 0) )) irProg.lines().size shouldBe 10 val opt = IRPeepholeOptimizer(irProg) @@ -123,8 +123,8 @@ class TestIRPeepholeOpt: FunSpec({ test("replace add/sub 1 by inc/dec") { val irProg = makeIRProgram(listOf( - IRInstruction(Opcode.ADD, VmDataType.BYTE, reg1=42, value = 1), - IRInstruction(Opcode.SUB, VmDataType.BYTE, reg1=42, value = 1) + IRInstruction(Opcode.ADD, IRDataType.BYTE, reg1=42, value = 1), + IRInstruction(Opcode.SUB, IRDataType.BYTE, reg1=42, value = 1) )) irProg.lines().size shouldBe 2 val opt = IRPeepholeOptimizer(irProg) @@ -137,14 +137,14 @@ class TestIRPeepholeOpt: FunSpec({ test("remove useless and/or/xor") { val irProg = makeIRProgram(listOf( - IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 255), - IRInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 65535), - IRInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 0), - IRInstruction(Opcode.XOR, VmDataType.BYTE, reg1=42, value = 0), - IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 200), - IRInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 60000), - IRInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 1), - IRInstruction(Opcode.XOR, VmDataType.BYTE, reg1=42, value = 1) + IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, value = 255), + IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, value = 65535), + IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, value = 0), + IRInstruction(Opcode.XOR, IRDataType.BYTE, reg1=42, value = 0), + IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, value = 200), + IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, value = 60000), + IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, value = 1), + IRInstruction(Opcode.XOR, IRDataType.BYTE, reg1=42, value = 1) )) irProg.lines().size shouldBe 8 val opt = IRPeepholeOptimizer(irProg) @@ -155,10 +155,10 @@ class TestIRPeepholeOpt: FunSpec({ test("replace and/or/xor by constant number") { val irProg = makeIRProgram(listOf( - IRInstruction(Opcode.AND, VmDataType.BYTE, reg1=42, value = 0), - IRInstruction(Opcode.AND, VmDataType.WORD, reg1=42, value = 0), - IRInstruction(Opcode.OR, VmDataType.BYTE, reg1=42, value = 255), - IRInstruction(Opcode.OR, VmDataType.WORD, reg1=42, value = 65535) + IRInstruction(Opcode.AND, IRDataType.BYTE, reg1=42, value = 0), + IRInstruction(Opcode.AND, IRDataType.WORD, reg1=42, value = 0), + IRInstruction(Opcode.OR, IRDataType.BYTE, reg1=42, value = 255), + IRInstruction(Opcode.OR, IRDataType.WORD, reg1=42, value = 65535) )) irProg.lines().size shouldBe 4 val opt = IRPeepholeOptimizer(irProg) diff --git a/compiler/test/TestLaunchEmu.kt b/compiler/test/TestLaunchEmu.kt index c6451844d..9136f49f3 100644 --- a/compiler/test/TestLaunchEmu.kt +++ b/compiler/test/TestLaunchEmu.kt @@ -15,6 +15,9 @@ class TestLaunchEmu: FunSpec({ + + + diff --git a/examples/test.p8 b/examples/test.p8 index 7506bbfcc..fb81add50 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,28 +1,4 @@ -%option enable_floats - main { sub start() { - %asm {{ - lda #99 - rts - }} - - %ir {{ - nop - loadr r1,r2 - return - }} - - ubyte @shared @zp var1 = 42 - uword @shared @zp var2 = 4242 - str @shared name = "irmen" - ubyte[] @shared array1 = [11,22,33,44] - uword[5] @shared array2 = 9999 - uword[5] @shared array3 - float @shared fvar = 1.234 - float @shared fvar2 - float[] @shared farray1 = [1.11,2.22,3.33] - float[5] @shared farray2 = 999.9 - float[5] @shared farray3 } } diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index d00758a18..e13c706ed 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -27,6 +27,7 @@ class IRFileReader { val match = programPattern.matchEntire(line) ?: throw IRParseException("invalid PROGRAM") val programName = match.groups[1]!!.value val options = parseOptions(lines) + val asmsymbols = parseAsmSymbols(lines) val variables = parseVariables(lines, options.dontReinitGlobals) val memorymapped = parseMemMapped(lines) val slabs = parseSlabs(lines) @@ -34,6 +35,7 @@ class IRFileReader { val blocks = parseBlocksUntilProgramEnd(lines, variables) val st = IRSymbolTable(null) + asmsymbols.forEach { (name, value) -> st.addAsmSymbol(name, value)} variables.forEach { st.add(it) } memorymapped.forEach { st.add(it) } slabs.forEach { st.add(it) } @@ -44,6 +46,22 @@ class IRFileReader { return program } + private fun parseAsmSymbols(lines: Iterator): Map { + val symbols = mutableMapOf() + var line = lines.next() + while(line.isBlank()) + line = lines.next() + if(line!="") + throw IRParseException("invalid ASMSYMBOLS") + while(true) { + line = lines.next() + if(line=="") + return symbols + val (name, value) = line.split('=') + symbols[name] = value + } + } + private fun parseOptions(lines: Iterator): CompilationOptions { var line = lines.next() while(line.isBlank()) diff --git a/intermediate/src/prog8/intermediate/IRFileWriter.kt b/intermediate/src/prog8/intermediate/IRFileWriter.kt index 0e0f993c1..47bd72e1f 100644 --- a/intermediate/src/prog8/intermediate/IRFileWriter.kt +++ b/intermediate/src/prog8/intermediate/IRFileWriter.kt @@ -18,6 +18,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) { println("Writing intermediate representation to $outfile") out.write("\n") writeOptions() + writeAsmSymbols() writeVariableAllocations() out.write("\n\n") @@ -36,6 +37,12 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) { return outfile } + private fun writeAsmSymbols() { + out.write("\n") + irProgram.asmSymbols.forEach { (name, value) -> out.write("$name=$value\n" )} + out.write("\n") + } + private fun writeBlocks() { irProgram.blocks.forEach { block -> out.write("\n\n") diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 08dec8e50..f5833c085 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -51,6 +51,7 @@ But you can decide whatever you want because here we just care about jumping and Saving/restoring registers is possible with PUSH and POP instructions. jump location - continue running at instruction number given by location +jumpa address - continue running at memory address (note: only used to encode a physical cpu jump to fixed address instruction) call location - save current instruction location+1, continue execution at instruction nr given by location calli reg1 - save current instruction location+1, continue execution at instruction number in reg1 syscall value - do a systemcall identified by call number @@ -67,6 +68,8 @@ bsteq address - branch to location if Status bit Zero bstne address - branch to location if Status bit Zero is not set bstneg address - branch to location if Status bit Negative is not set bstpos address - branch to location if Status bit Negative is not set +bstvc address - branch to location if Status bit Overflow is not set +bstvs address - branch to location if Status bit Overflow is not set bz reg1, address - branch to location if reg1 is zero bnz reg1, address - branch to location if reg1 is not zero beq reg1, reg2, address - jump to location in program given by location, if reg1 == reg2 @@ -223,6 +226,7 @@ enum class Opcode { STOREZX, JUMP, + JUMPA, CALL, SYSCALL, RETURN, @@ -233,6 +237,8 @@ enum class Opcode { BSTNE, BSTNEG, BSTPOS, + BSTVC, + BSTVS, BZ, BNZ, BEQ, @@ -359,6 +365,7 @@ val OpcodesWithAddress = setOf( Opcode.STOREZM, Opcode.STOREZX, Opcode.JUMP, + Opcode.JUMPA, Opcode.CALL, Opcode.INCM, Opcode.DECM, @@ -404,6 +411,7 @@ val OpcodesWithAddress = setOf( val OpcodesThatBranch = setOf( Opcode.JUMP, + Opcode.JUMPA, Opcode.RETURN, Opcode.BSTCC, Opcode.BSTCS, @@ -411,6 +419,8 @@ val OpcodesThatBranch = setOf( Opcode.BSTNE, Opcode.BSTNEG, Opcode.BSTPOS, + Opcode.BSTVC, + Opcode.BSTVS, Opcode.BZ, Opcode.BNZ, Opcode.BEQ, @@ -432,7 +442,7 @@ val OpcodesForCpuRegisters = setOf( ) -enum class VmDataType { +enum class IRDataType { BYTE, WORD, FLOAT @@ -445,7 +455,7 @@ enum class OperandDirection { INOUT } -data class InstructionFormat(val datatype: VmDataType?, +data class InstructionFormat(val datatype: IRDataType?, val reg1: Boolean, val reg1direction: OperandDirection, // reg1 can be IN/OUT/INOUT val reg2: Boolean, // always only IN val fpReg1: Boolean, val fpReg1direction: OperandDirection, // fpreg1 can be IN/OUT/INOUT @@ -454,8 +464,8 @@ data class InstructionFormat(val datatype: VmDataType?, val fpValue: Boolean // always only IN ) { companion object { - fun from(spec: String): Map { - val result = mutableMapOf() + fun from(spec: String): Map { + val result = mutableMapOf() for(part in spec.split('|').map{ it.trim() }) { var reg1 = false // read/write/modify possible var reg1Direction = OperandDirection.INPUT @@ -485,11 +495,11 @@ data class InstructionFormat(val datatype: VmDataType?, if(typespec=="N") result[null] = InstructionFormat(null, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) if('B' in typespec) - result[VmDataType.BYTE] = InstructionFormat(VmDataType.BYTE, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) + result[IRDataType.BYTE] = InstructionFormat(IRDataType.BYTE, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) if('W' in typespec) - result[VmDataType.WORD] = InstructionFormat(VmDataType.WORD, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) + result[IRDataType.WORD] = InstructionFormat(IRDataType.WORD, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) if('F' in typespec) - result[VmDataType.FLOAT] = InstructionFormat(VmDataType.FLOAT, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) + result[IRDataType.FLOAT] = InstructionFormat(IRDataType.FLOAT, reg1, reg1Direction, reg2, fpreg1, fpreg1Direction, fpreg2, value, fpvalue) } return result } @@ -522,6 +532,7 @@ val instructionFormats = mutableMapOf( Opcode.STOREZI to InstructionFormat.from("BW, require(value in -128..255) {"value out of range for byte: $value"} - VmDataType.WORD -> require(value in -32768..65535) {"value out of range for word: $value"} - VmDataType.FLOAT, null -> {} + IRDataType.BYTE -> require(value in -128..255) {"value out of range for byte: $value"} + IRDataType.WORD -> require(value in -32768..65535) {"value out of range for word: $value"} + IRDataType.FLOAT, null -> {} } } @@ -694,7 +707,7 @@ data class IRInstruction( if(!format.fpReg1) require(fpReg1==null) { "invalid fpReg1" } if(!format.fpReg2) require(fpReg2==null) { "invalid fpReg2" } - if (type==VmDataType.FLOAT) { + if (type==IRDataType.FLOAT) { if(format.fpValue) require(fpValue!=null || labelSymbol!=null) {"missing a fp-value or labelsymbol"} } else { if(format.value) require(value!=null || labelSymbol!=null) {"missing a value or labelsymbol"} @@ -710,7 +723,7 @@ data class IRInstruction( Opcode.SEQ, Opcode.SNE, Opcode.SLT, Opcode.SLTS, Opcode.SGT, Opcode.SGTS, Opcode.SLE, Opcode.SLES, Opcode.SGE, Opcode.SGES)) { - if(type==VmDataType.FLOAT) + if(type==IRDataType.FLOAT) require(fpReg1!=fpReg2) {"$opcode: fpReg1 and fpReg2 should be different"} else require(reg1!=reg2) {"$opcode: reg1 and reg2 should be different"} @@ -721,9 +734,9 @@ data class IRInstruction( val result = mutableListOf(opcode.name.lowercase()) when(type) { - VmDataType.BYTE -> result.add(".b ") - VmDataType.WORD -> result.add(".w ") - VmDataType.FLOAT -> result.add(".f ") + IRDataType.BYTE -> result.add(".b ") + IRDataType.WORD -> result.add(".w ") + IRDataType.FLOAT -> result.add(".f ") else -> result.add(" ") } reg1?.let { diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index 554afbc4d..1e4fb1a1d 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -10,6 +10,7 @@ note: all symbol names are flattened so that they're a single string that is glo PROGRAM: OPTIONS (from CompilationOptions) + ASMSYMBOLS (from command line defined symbols) VARIABLES (from Symboltable) MEMORYMAPPEDVARIABLES (from Symboltable) MEMORYSLABS (from Symboltable) @@ -50,6 +51,7 @@ class IRProgram(val name: String, val options: CompilationOptions, val encoding: IStringEncoding) { + val asmSymbols = mutableMapOf() val globalInits = mutableListOf() val blocks = mutableListOf() @@ -58,6 +60,10 @@ class IRProgram(val name: String, require(blocks.all { it.name != block.name}) { "duplicate block ${block.name} ${block.position}" } blocks.add(block) } + + fun addAsmSymbols(symbolDefs: Map) { + asmSymbols += symbolDefs + } } class IRBlock( diff --git a/intermediate/src/prog8/intermediate/IRSymbolTable.kt b/intermediate/src/prog8/intermediate/IRSymbolTable.kt index b78d96f99..ebcc491f8 100644 --- a/intermediate/src/prog8/intermediate/IRSymbolTable.kt +++ b/intermediate/src/prog8/intermediate/IRSymbolTable.kt @@ -8,6 +8,7 @@ import prog8.code.* class IRSymbolTable(sourceSt: SymbolTable?) { private val table = mutableMapOf() + private val asmSymbols = mutableMapOf() init { if(sourceSt!=null) { @@ -103,4 +104,10 @@ class IRSymbolTable(sourceSt: SymbolTable?) { StMemorySlab("prog8_slabs.${variable.name}", variable.size, variable.align, variable.position) table[varToadd.name] = varToadd } + + fun addAsmSymbol(name: String, value: String) { + asmSymbols[name] = value + } + + fun getAsmSymbols(): Map = asmSymbols } diff --git a/intermediate/src/prog8/intermediate/Utils.kt b/intermediate/src/prog8/intermediate/Utils.kt index 666dff503..bd06c55b3 100644 --- a/intermediate/src/prog8/intermediate/Utils.kt +++ b/intermediate/src/prog8/intermediate/Utils.kt @@ -54,12 +54,12 @@ fun getTypeString(variable : StStaticVariable): String { } } -fun convertIRType(typestr: String): VmDataType? { +fun convertIRType(typestr: String): IRDataType? { return when(typestr.lowercase()) { "" -> null - ".b" -> VmDataType.BYTE - ".w" -> VmDataType.WORD - ".f" -> VmDataType.FLOAT + ".b" -> IRDataType.BYTE + ".w" -> IRDataType.WORD + ".f" -> IRDataType.FLOAT else -> throw IRParseException("invalid type $typestr") } } @@ -100,11 +100,11 @@ fun parseIRCodeLine(line: String, pc: Int, placeholders: MutableMap } catch (ax: IllegalArgumentException) { throw IRParseException("invalid vmasm instruction: $instr") } - var type: VmDataType? = convertIRType(typestr) + var type: IRDataType? = convertIRType(typestr) val formats = instructionFormats.getValue(opcode) val format: InstructionFormat if(type !in formats) { - type = VmDataType.BYTE + type = IRDataType.BYTE format = if(type !in formats) formats.getValue(null) else @@ -207,15 +207,15 @@ fun parseIRCodeLine(line: String, pc: Int, placeholders: MutableMap throw IRParseException("invalid reg2 for $line") if(value!=null && opcode !in OpcodesWithAddress) { when (type) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { if (value < -128 || value > 255) throw IRParseException("value out of range for byte: $value") } - VmDataType.WORD -> { + IRDataType.WORD -> { if (value < -32768 || value > 65535) throw IRParseException("value out of range for word: $value") } - VmDataType.FLOAT -> {} + IRDataType.FLOAT -> {} null -> {} } } diff --git a/intermediate/test/TestIRFileInOut.kt b/intermediate/test/TestIRFileInOut.kt index 64654d56f..61e080bcf 100644 --- a/intermediate/test/TestIRFileInOut.kt +++ b/intermediate/test/TestIRFileInOut.kt @@ -51,6 +51,9 @@ dontReinitGlobals=false evalStackBaseAddress=null + + + uword sys.wait.jiffies= zp=DONTCARE diff --git a/intermediate/test/TestInstructions.kt b/intermediate/test/TestInstructions.kt index d0f960985..5d530d4f3 100644 --- a/intermediate/test/TestInstructions.kt +++ b/intermediate/test/TestInstructions.kt @@ -22,9 +22,9 @@ class TestInstructions: FunSpec({ } test("with value") { - val ins = IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=42, value = 99) + val ins = IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=42, value = 99) ins.opcode shouldBe Opcode.BZ - ins.type shouldBe VmDataType.BYTE + ins.type shouldBe IRDataType.BYTE ins.reg1 shouldBe 42 ins.reg2 shouldBe null ins.value shouldBe 99 @@ -35,9 +35,9 @@ class TestInstructions: FunSpec({ } test("with label") { - val ins = IRInstruction(Opcode.BZ, VmDataType.WORD, reg1=11, labelSymbol = "a.b.c") + val ins = IRInstruction(Opcode.BZ, IRDataType.WORD, reg1=11, labelSymbol = "a.b.c") ins.opcode shouldBe Opcode.BZ - ins.type shouldBe VmDataType.WORD + ins.type shouldBe IRDataType.WORD ins.reg1 shouldBe 11 ins.reg2 shouldBe null ins.value shouldBe null @@ -48,9 +48,9 @@ class TestInstructions: FunSpec({ } test("with output registers") { - val ins = IRInstruction(Opcode.ADDR, VmDataType.WORD, reg1=11, reg2=22) + val ins = IRInstruction(Opcode.ADDR, IRDataType.WORD, reg1=11, reg2=22) ins.opcode shouldBe Opcode.ADDR - ins.type shouldBe VmDataType.WORD + ins.type shouldBe IRDataType.WORD ins.reg1 shouldBe 11 ins.reg2 shouldBe 22 ins.value shouldBe null @@ -59,9 +59,9 @@ class TestInstructions: FunSpec({ ins.fpReg1direction shouldBe OperandDirection.INPUT ins.toString() shouldBe "addr.w r11,r22" - val ins2 = IRInstruction(Opcode.SQRT, VmDataType.BYTE, reg1=11, reg2=22) + val ins2 = IRInstruction(Opcode.SQRT, IRDataType.BYTE, reg1=11, reg2=22) ins2.opcode shouldBe Opcode.SQRT - ins2.type shouldBe VmDataType.BYTE + ins2.type shouldBe IRDataType.BYTE ins2.reg1 shouldBe 11 ins2.reg2 shouldBe 22 ins2.value shouldBe null @@ -80,13 +80,13 @@ class TestInstructions: FunSpec({ test("missing registers should fail") { shouldThrowWithMessage("missing reg1") { - IRInstruction(Opcode.BZ, VmDataType.BYTE, value=99) + IRInstruction(Opcode.BZ, IRDataType.BYTE, value=99) } } test("missing value should fail") { shouldThrowWithMessage("missing a value or labelsymbol") { - IRInstruction(Opcode.BZ, VmDataType.BYTE, reg1=42) + IRInstruction(Opcode.BZ, IRDataType.BYTE, reg1=42) } } diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index e37290000..1ca62bc12 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -46,6 +46,7 @@ class VirtualMachine(irProgram: IRProgram) { init { program = VmProgramLoader().load(irProgram, memory).toTypedArray() require(program.size<=65536) {"program cannot contain more than 65536 instructions"} + require(irProgram.st.getAsmSymbols().isEmpty()) { "virtual machine can't yet process asmsymbols defined on command line" } cx16virtualregsBaseAddress = (irProgram.st.lookup("cx16.r0") as? StMemVar)?.address?.toInt() ?: 0xff02 } @@ -120,6 +121,7 @@ class VirtualMachine(irProgram: IRProgram) { Opcode.STOREZX -> InsSTOREZX(ins) Opcode.STOREZI -> InsSTOREZI(ins) Opcode.JUMP -> InsJUMP(ins) + Opcode.JUMPA -> throw IllegalArgumentException("vm program can't jump to system memory address (JUMPA)") Opcode.CALL -> InsCALL(ins) Opcode.SYSCALL -> InsSYSCALL(ins) Opcode.RETURN -> InsRETURN() @@ -129,6 +131,7 @@ class VirtualMachine(irProgram: IRProgram) { Opcode.BSTNE -> InsBSTNE(ins) Opcode.BSTNEG -> InsBSTNEG(ins) Opcode.BSTPOS -> InsBSTPOS(ins) + Opcode.BSTVC, Opcode.BSTVS -> TODO("overflow status flag not yet supported in VM (BSTVC,BSTVS)") Opcode.BZ -> InsBZ(ins) Opcode.BNZ -> InsBNZ(ins) Opcode.BEQ -> InsBEQ(ins) @@ -151,7 +154,6 @@ class VirtualMachine(irProgram: IRProgram) { Opcode.SLES -> InsSLES(ins) Opcode.SGE -> InsSGE(ins) Opcode.SGES -> InsSGES(ins) - Opcode.INC -> InsINC(ins) Opcode.INCM -> InsINCM(ins) Opcode.DEC -> InsDEC(ins) @@ -248,11 +250,11 @@ class VirtualMachine(irProgram: IRProgram) { } } - private inline fun setResultReg(reg: Int, value: Int, type: VmDataType) { + private inline fun setResultReg(reg: Int, value: Int, type: IRDataType) { when(type) { - VmDataType.BYTE -> registers.setUB(reg, value.toUByte()) - VmDataType.WORD -> registers.setUW(reg, value.toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("attempt to set integer result register but float type") + IRDataType.BYTE -> registers.setUB(reg, value.toUByte()) + IRDataType.WORD -> registers.setUW(reg, value.toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("attempt to set integer result register but float type") } } @@ -261,16 +263,16 @@ class VirtualMachine(irProgram: IRProgram) { throw StackOverflowError("valuestack limit 128 exceeded") when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = registers.getUB(i.reg1!!) valueStack.push(value) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = registers.getUW(i.reg1!!) valueStack.push((value and 255u).toUByte()) valueStack.push((value.toInt() ushr 8).toUByte()) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { throw IllegalArgumentException("can't PUSH a float") } } @@ -279,15 +281,15 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsPOP(i: IRInstruction) { val value = when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { valueStack.pop().toInt() } - VmDataType.WORD -> { + IRDataType.WORD -> { val msb = valueStack.pop() val lsb = valueStack.pop() (msb.toInt() shl 8) + lsb.toInt() } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { throw IllegalArgumentException("can't POP a float") } } @@ -329,8 +331,8 @@ class VirtualMachine(irProgram: IRProgram) { } } when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort()) + IRDataType.BYTE -> registers.setUB(i.reg1!!, value.toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, value.toUShort()) else -> throw java.lang.IllegalArgumentException("invalid cpu reg type") } pc++ @@ -338,9 +340,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsSTORECPU(i: IRInstruction) { val value: UInt = when(i.type!!) { - VmDataType.BYTE -> registers.getUB(i.reg1!!).toUInt() - VmDataType.WORD -> registers.getUW(i.reg1!!).toUInt() - VmDataType.FLOAT -> throw IllegalArgumentException("there are no float cpu registers") + IRDataType.BYTE -> registers.getUB(i.reg1!!).toUInt() + IRDataType.WORD -> registers.getUW(i.reg1!!).toUInt() + IRDataType.FLOAT -> throw IllegalArgumentException("there are no float cpu registers") } StoreCPU(value, i.type!!, i.labelSymbol!!) pc++ @@ -351,13 +353,13 @@ class VirtualMachine(irProgram: IRProgram) { pc++ } - private fun StoreCPU(value: UInt, dt: VmDataType, regStr: String) { + private fun StoreCPU(value: UInt, dt: IRDataType, regStr: String) { if(regStr.startsWith('r')) { val regnum = regStr.substring(1).toInt() val regAddr = cx16virtualregsBaseAddress + regnum*2 when(dt) { - VmDataType.BYTE -> memory.setUB(regAddr, value.toUByte()) - VmDataType.WORD -> memory.setUW(regAddr, value.toUShort()) + IRDataType.BYTE -> memory.setUB(regAddr, value.toUByte()) + IRDataType.WORD -> memory.setUW(regAddr, value.toUShort()) else -> throw IllegalArgumentException("invalid reg dt") } } else { @@ -387,7 +389,7 @@ class VirtualMachine(irProgram: IRProgram) { } private fun InsLOAD(i: IRInstruction) { - if(i.type==VmDataType.FLOAT) + if(i.type==IRDataType.FLOAT) registers.setFloat(i.fpReg1!!, i.fpValue!!) else setResultReg(i.reg1!!, i.value!!, i.type!!) @@ -396,42 +398,42 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsLOADM(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!!)) - VmDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!!)) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!!)) + IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!!)) + IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!!)) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!!)) } pc++ } private fun InsLOADI(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(registers.getUW(i.reg2!!).toInt())) - VmDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(registers.getUW(i.reg2!!).toInt())) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt())) + IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(registers.getUW(i.reg2!!).toInt())) + IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(registers.getUW(i.reg2!!).toInt())) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(registers.getUW(i.reg1!!).toInt())) } pc++ } private fun InsLOADX(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!! + registers.getUW(i.reg2!!).toInt())) - VmDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!! + registers.getUW(i.reg2!!).toInt())) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!! + registers.getUW(i.reg1!!).toInt())) + IRDataType.BYTE -> registers.setUB(i.reg1!!, memory.getUB(i.value!! + registers.getUW(i.reg2!!).toInt())) + IRDataType.WORD -> registers.setUW(i.reg1!!, memory.getUW(i.value!! + registers.getUW(i.reg2!!).toInt())) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, memory.getFloat(i.value!! + registers.getUW(i.reg1!!).toInt())) } pc++ } private fun InsLOADIX(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!) registers.setUB(i.reg1!!, memory.getUB(pointer.toInt())) } - VmDataType.WORD -> { + IRDataType.WORD -> { val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!) registers.setUW(i.reg1!!, memory.getUW(pointer.toInt())) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg1!!) registers.setFloat(i.fpReg1!!, memory.getFloat(pointer.toInt())) } @@ -441,51 +443,51 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsLOADR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg2!!)) - VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg2!!)) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!)) + IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg2!!)) + IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg2!!)) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!)) } pc++ } private fun InsSTOREM(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> memory.setUB(i.value!!, registers.getUB(i.reg1!!)) - VmDataType.WORD -> memory.setUW(i.value!!, registers.getUW(i.reg1!!)) - VmDataType.FLOAT -> memory.setFloat(i.value!!, registers.getFloat(i.fpReg1!!)) + IRDataType.BYTE -> memory.setUB(i.value!!, registers.getUB(i.reg1!!)) + IRDataType.WORD -> memory.setUW(i.value!!, registers.getUW(i.reg1!!)) + IRDataType.FLOAT -> memory.setFloat(i.value!!, registers.getFloat(i.fpReg1!!)) } pc++ } private fun InsSTOREI(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt(), registers.getUB(i.reg1!!)) - VmDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt(), registers.getUW(i.reg1!!)) - VmDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!)) + IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt(), registers.getUB(i.reg1!!)) + IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt(), registers.getUW(i.reg1!!)) + IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), registers.getFloat(i.fpReg1!!)) } pc++ } private fun InsSTOREX(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + i.value!!, registers.getUB(i.reg1!!)) - VmDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt() + i.value!!, registers.getUW(i.reg1!!)) - VmDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.value!!, registers.getFloat(i.fpReg1!!)) + IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg2!!).toInt() + i.value!!, registers.getUB(i.reg1!!)) + IRDataType.WORD -> memory.setUW(registers.getUW(i.reg2!!).toInt() + i.value!!, registers.getUW(i.reg1!!)) + IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.value!!, registers.getFloat(i.fpReg1!!)) } pc++ } private fun InsSTOREIX(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!) memory.setUB(pointer.toInt(), registers.getUB(i.reg1!!)) } - VmDataType.WORD -> { + IRDataType.WORD -> { val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg2!!) memory.setUW(pointer.toInt(), registers.getUW(i.reg1!!)) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { val pointer = memory.getUW(i.value!!) + registers.getUB(i.reg1!!) memory.setFloat(pointer.toInt(), registers.getFloat(i.fpReg1!!)) } @@ -495,27 +497,27 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsSTOREZM(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> memory.setUB(i.value!!, 0u) - VmDataType.WORD -> memory.setUW(i.value!!, 0u) - VmDataType.FLOAT -> memory.setFloat(i.value!!, 0f) + IRDataType.BYTE -> memory.setUB(i.value!!, 0u) + IRDataType.WORD -> memory.setUW(i.value!!, 0u) + IRDataType.FLOAT -> memory.setFloat(i.value!!, 0f) } pc++ } private fun InsSTOREZI(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt(), 0u) - VmDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt(), 0u) - VmDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), 0f) + IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt(), 0u) + IRDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt(), 0u) + IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt(), 0f) } pc++ } private fun InsSTOREZX(i: IRInstruction) { when (i.type!!) { - VmDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt() + i.value!!, 0u) - VmDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt() + i.value!!, 0u) - VmDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.value!!, 0f) + IRDataType.BYTE -> memory.setUB(registers.getUW(i.reg1!!).toInt() + i.value!!, 0u) + IRDataType.WORD -> memory.setUW(registers.getUW(i.reg1!!).toInt() + i.value!!, 0u) + IRDataType.FLOAT -> memory.setFloat(registers.getUW(i.reg1!!).toInt() + i.value!!, 0f) } pc++ } @@ -580,37 +582,37 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsBZ(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { if(registers.getUB(i.reg1!!)==0.toUByte()) pc = i.value!! else pc++ } - VmDataType.WORD -> { + IRDataType.WORD -> { if(registers.getUW(i.reg1!!)==0.toUShort()) pc = i.value!! else pc++ } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } } private fun InsBNZ(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { if(registers.getUB(i.reg1!!)!=0.toUByte()) pc = i.value!! else pc++ } - VmDataType.WORD -> { + IRDataType.WORD -> { if(registers.getUW(i.reg1!!)!=0.toUShort()) pc = i.value!! else pc++ } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } } @@ -771,9 +773,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsINC(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (registers.getUB(i.reg1!!)+1u).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (registers.getUW(i.reg1!!)+1u).toUShort()) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)+1f) + IRDataType.BYTE -> registers.setUB(i.reg1!!, (registers.getUB(i.reg1!!)+1u).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (registers.getUW(i.reg1!!)+1u).toUShort()) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)+1f) } pc++ } @@ -781,36 +783,36 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsINCM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> memory.setUB(address, (memory.getUB(address)+1u).toUByte()) - VmDataType.WORD -> memory.setUW(address, (memory.getUW(address)+1u).toUShort()) - VmDataType.FLOAT -> memory.setFloat(address, memory.getFloat(address)+1f) + IRDataType.BYTE -> memory.setUB(address, (memory.getUB(address)+1u).toUByte()) + IRDataType.WORD -> memory.setUW(address, (memory.getUW(address)+1u).toUShort()) + IRDataType.FLOAT -> memory.setFloat(address, memory.getFloat(address)+1f) } pc++ } private fun InsDEC(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (registers.getUB(i.reg1!!)-1u).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (registers.getUW(i.reg1!!)-1u).toUShort()) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)-1f) + IRDataType.BYTE -> registers.setUB(i.reg1!!, (registers.getUB(i.reg1!!)-1u).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (registers.getUW(i.reg1!!)-1u).toUShort()) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg1!!)-1f) } pc++ } private fun InsDECM(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> memory.setUB(i.value!!, (memory.getUB(i.value!!)-1u).toUByte()) - VmDataType.WORD -> memory.setUW(i.value!!, (memory.getUW(i.value!!)-1u).toUShort()) - VmDataType.FLOAT -> memory.setFloat(i.value!!, memory.getFloat(i.value!!)-1f) + IRDataType.BYTE -> memory.setUB(i.value!!, (memory.getUB(i.value!!)-1u).toUByte()) + IRDataType.WORD -> memory.setUW(i.value!!, (memory.getUW(i.value!!)-1u).toUShort()) + IRDataType.FLOAT -> memory.setFloat(i.value!!, memory.getFloat(i.value!!)-1f) } pc++ } private fun InsNEG(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (-registers.getUB(i.reg1!!).toInt()).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (-registers.getUW(i.reg1!!).toInt()).toUShort()) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, -registers.getFloat(i.fpReg1!!)) + IRDataType.BYTE -> registers.setUB(i.reg1!!, (-registers.getUB(i.reg1!!).toInt()).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (-registers.getUW(i.reg1!!).toInt()).toUShort()) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, -registers.getFloat(i.fpReg1!!)) } pc++ } @@ -818,18 +820,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsNEGM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> memory.setUB(address, (-memory.getUB(address).toInt()).toUByte()) - VmDataType.WORD -> memory.setUW(address, (-memory.getUW(address).toInt()).toUShort()) - VmDataType.FLOAT -> memory.setFloat(address, -memory.getFloat(address)) + IRDataType.BYTE -> memory.setUB(address, (-memory.getUB(address).toInt()).toUByte()) + IRDataType.WORD -> memory.setUW(address, (-memory.getUW(address).toInt()).toUShort()) + IRDataType.FLOAT -> memory.setFloat(address, -memory.getFloat(address)) } pc++ } private fun InsADDR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> plusMinusMultAnyByte("+", i.reg1!!, i.reg2!!) - VmDataType.WORD -> plusMinusMultAnyWord("+", i.reg1!!, i.reg2!!) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultAnyByte("+", i.reg1!!, i.reg2!!) + IRDataType.WORD -> plusMinusMultAnyWord("+", i.reg1!!, i.reg2!!) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg2!!) val result = arithFloat(left, "+", right) @@ -841,9 +843,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsADD(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.value!!.toUByte()) - VmDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.value!!.toUShort()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultConstByte("+", i.reg1!!, i.value!!.toUByte()) + IRDataType.WORD -> plusMinusMultConstWord("+", i.reg1!!, i.value!!.toUShort()) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "+", i.fpValue!!) registers.setFloat(i.fpReg1!!, result) @@ -855,9 +857,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsADDM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> plusMinusMultAnyByteInplace("+", i.reg1!!, address) - VmDataType.WORD -> plusMinusMultAnyWordInplace("+", i.reg1!!, address) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultAnyByteInplace("+", i.reg1!!, address) + IRDataType.WORD -> plusMinusMultAnyWordInplace("+", i.reg1!!, address) + IRDataType.FLOAT -> { val left = memory.getFloat(address) val right = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "+", right) @@ -869,9 +871,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsSUBR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> plusMinusMultAnyByte("-", i.reg1!!, i.reg2!!) - VmDataType.WORD -> plusMinusMultAnyWord("-", i.reg1!!, i.reg2!!) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultAnyByte("-", i.reg1!!, i.reg2!!) + IRDataType.WORD -> plusMinusMultAnyWord("-", i.reg1!!, i.reg2!!) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg2!!) val result = arithFloat(left, "-", right) @@ -883,9 +885,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsSUB(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.value!!.toUByte()) - VmDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.value!!.toUShort()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultConstByte("-", i.reg1!!, i.value!!.toUByte()) + IRDataType.WORD -> plusMinusMultConstWord("-", i.reg1!!, i.value!!.toUShort()) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "-", i.fpValue!!) registers.setFloat(i.fpReg1!!, result) @@ -897,9 +899,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsSUBM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> plusMinusMultAnyByteInplace("-", i.reg1!!, address) - VmDataType.WORD -> plusMinusMultAnyWordInplace("-", i.reg1!!, address) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultAnyByteInplace("-", i.reg1!!, address) + IRDataType.WORD -> plusMinusMultAnyWordInplace("-", i.reg1!!, address) + IRDataType.FLOAT -> { val left = memory.getFloat(address) val right = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "-", right) @@ -911,9 +913,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsMULR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> plusMinusMultAnyByte("*", i.reg1!!, i.reg2!!) - VmDataType.WORD -> plusMinusMultAnyWord("*", i.reg1!!, i.reg2!!) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultAnyByte("*", i.reg1!!, i.reg2!!) + IRDataType.WORD -> plusMinusMultAnyWord("*", i.reg1!!, i.reg2!!) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg2!!) val result = arithFloat(left, "*", right) @@ -925,9 +927,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsMUL(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.value!!.toUByte()) - VmDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.value!!.toUShort()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultConstByte("*", i.reg1!!, i.value!!.toUByte()) + IRDataType.WORD -> plusMinusMultConstWord("*", i.reg1!!, i.value!!.toUShort()) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "*", i.fpValue!!) registers.setFloat(i.fpReg1!!, result) @@ -939,9 +941,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsMULM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> plusMinusMultAnyByteInplace("*", i.reg1!!, address) - VmDataType.WORD -> plusMinusMultAnyWordInplace("*", i.reg1!!, address) - VmDataType.FLOAT -> { + IRDataType.BYTE -> plusMinusMultAnyByteInplace("*", i.reg1!!, address) + IRDataType.WORD -> plusMinusMultAnyWordInplace("*", i.reg1!!, address) + IRDataType.FLOAT -> { val left = memory.getFloat(address) val right = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "*", right) @@ -953,18 +955,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsDIVR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> divModByteUnsigned("/", i.reg1!!, i.reg2!!) - VmDataType.WORD -> divModWordUnsigned("/", i.reg1!!, i.reg2!!) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> divModByteUnsigned("/", i.reg1!!, i.reg2!!) + IRDataType.WORD -> divModWordUnsigned("/", i.reg1!!, i.reg2!!) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsDIV(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> divModConstByteUnsigned("/", i.reg1!!, i.value!!.toUByte()) - VmDataType.WORD -> divModConstWordUnsigned("/", i.reg1!!, i.value!!.toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> divModConstByteUnsigned("/", i.reg1!!, i.value!!.toUByte()) + IRDataType.WORD -> divModConstWordUnsigned("/", i.reg1!!, i.value!!.toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -972,18 +974,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsDIVM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> divModByteUnsignedInplace("/", i.reg1!!, address) - VmDataType.WORD -> divModWordUnsignedInplace("/", i.reg1!!, address) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> divModByteUnsignedInplace("/", i.reg1!!, address) + IRDataType.WORD -> divModWordUnsignedInplace("/", i.reg1!!, address) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsDIVSR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> divModByteSigned("/", i.reg1!!, i.reg2!!) - VmDataType.WORD -> divModWordSigned("/", i.reg1!!, i.reg2!!) - VmDataType.FLOAT -> { + IRDataType.BYTE -> divModByteSigned("/", i.reg1!!, i.reg2!!) + IRDataType.WORD -> divModWordSigned("/", i.reg1!!, i.reg2!!) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val right = registers.getFloat(i.fpReg2!!) val result = arithFloat(left, "/", right) @@ -995,9 +997,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsDIVS(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.value!!.toByte()) - VmDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.value!!.toShort()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> divModConstByteSigned("/", i.reg1!!, i.value!!.toByte()) + IRDataType.WORD -> divModConstWordSigned("/", i.reg1!!, i.value!!.toShort()) + IRDataType.FLOAT -> { val left = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "/", i.fpValue!!) registers.setFloat(i.fpReg1!!, result) @@ -1009,9 +1011,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsDIVSM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> divModByteSignedInplace("/", i.reg1!!, address) - VmDataType.WORD -> divModWordSignedInplace("/", i.reg1!!, address) - VmDataType.FLOAT -> { + IRDataType.BYTE -> divModByteSignedInplace("/", i.reg1!!, address) + IRDataType.WORD -> divModWordSignedInplace("/", i.reg1!!, address) + IRDataType.FLOAT -> { val left = memory.getFloat(address) val right = registers.getFloat(i.fpReg1!!) val result = arithFloat(left, "/", right) @@ -1023,45 +1025,45 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsMODR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> divModByteUnsigned("%", i.reg1!!, i.reg2!!) - VmDataType.WORD -> divModWordUnsigned("%", i.reg1!!, i.reg2!!) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> divModByteUnsigned("%", i.reg1!!, i.reg2!!) + IRDataType.WORD -> divModWordUnsigned("%", i.reg1!!, i.reg2!!) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsMOD(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> divModConstByteUnsigned("%", i.reg1!!, i.value!!.toUByte()) - VmDataType.WORD -> divModConstWordUnsigned("%", i.reg1!!, i.value!!.toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> divModConstByteUnsigned("%", i.reg1!!, i.value!!.toUByte()) + IRDataType.WORD -> divModConstWordUnsigned("%", i.reg1!!, i.value!!.toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsSGN(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setSB(i.reg1!!, registers.getSB(i.reg2!!).toInt().sign.toByte()) - VmDataType.WORD -> registers.setSW(i.reg1!!, registers.getSW(i.reg2!!).toInt().sign.toShort()) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!).sign) + IRDataType.BYTE -> registers.setSB(i.reg1!!, registers.getSB(i.reg2!!).toInt().sign.toByte()) + IRDataType.WORD -> registers.setSW(i.reg1!!, registers.getSW(i.reg2!!).toInt().sign.toShort()) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!).sign) } pc++ } private fun InsSQRT(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, sqrt(registers.getUB(i.reg2!!).toDouble()).toInt().toUByte()) - VmDataType.WORD -> registers.setUB(i.reg1!!, sqrt(registers.getUW(i.reg2!!).toDouble()).toInt().toUByte()) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, sqrt(registers.getFloat(i.fpReg2!!))) + IRDataType.BYTE -> registers.setUB(i.reg1!!, sqrt(registers.getUB(i.reg2!!).toDouble()).toInt().toUByte()) + IRDataType.WORD -> registers.setUB(i.reg1!!, sqrt(registers.getUW(i.reg2!!).toDouble()).toInt().toUByte()) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, sqrt(registers.getFloat(i.fpReg2!!))) } pc++ } private fun InsRND(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, Random.nextInt().toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, Random.nextInt().toUShort()) - VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, Random.nextFloat()) + IRDataType.BYTE -> registers.setUB(i.reg1!!, Random.nextInt().toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, Random.nextInt().toUShort()) + IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, Random.nextFloat()) } pc++ } @@ -1069,19 +1071,19 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsCMP(i: IRInstruction) { val comparison: Int when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val reg1 = registers.getUB(i.reg1!!) val reg2 = registers.getUB(i.reg2!!) comparison = reg1.toInt() - reg2.toInt() statusNegative = (comparison and 0x80)==0x80 } - VmDataType.WORD -> { + IRDataType.WORD -> { val reg1 = registers.getUW(i.reg1!!) val reg2 = registers.getUW(i.reg2!!) comparison = reg1.toInt() - reg2.toInt() statusNegative = (comparison and 0x8000)==0x8000 } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } if(comparison==0){ statusZero = true @@ -1383,18 +1385,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsEXT(i: IRInstruction) { when(i.type!!){ - VmDataType.BYTE -> registers.setUW(i.reg1!!, registers.getUB(i.reg1!!).toUShort()) - VmDataType.WORD -> throw IllegalArgumentException("ext.w not yet supported, requires 32 bits registers") - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUW(i.reg1!!, registers.getUB(i.reg1!!).toUShort()) + IRDataType.WORD -> throw IllegalArgumentException("ext.w not yet supported, requires 32 bits registers") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsEXTS(i: IRInstruction) { when(i.type!!){ - VmDataType.BYTE -> registers.setSW(i.reg1!!, registers.getSB(i.reg1!!).toShort()) - VmDataType.WORD -> throw IllegalArgumentException("exts.w not yet supported, requires 32 bits registers") - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setSW(i.reg1!!, registers.getSB(i.reg1!!).toShort()) + IRDataType.WORD -> throw IllegalArgumentException("exts.w not yet supported, requires 32 bits registers") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1402,18 +1404,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsANDR(i: IRInstruction) { val (left: UInt, right: UInt) = getLogicalOperandsU(i) when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (left and right).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (left and right).toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, (left and right).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (left and right).toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsAND(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) and i.value!!.toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) and i.value!!.toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) and i.value!!.toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) and i.value!!.toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1421,17 +1423,17 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsANDM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val left = memory.getUB(address) val right = registers.getUB(i.reg1!!) memory.setUB(address, left and right) } - VmDataType.WORD -> { + IRDataType.WORD -> { val left = memory.getUW(address) val right = registers.getUW(i.reg1!!) memory.setUW(address, left and right) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1439,18 +1441,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsORR(i: IRInstruction) { val (left: UInt, right: UInt) = getLogicalOperandsU(i) when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (left or right).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (left or right).toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, (left or right).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (left or right).toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsOR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) or i.value!!.toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) or i.value!!.toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) or i.value!!.toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) or i.value!!.toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1458,17 +1460,17 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsORM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val left = memory.getUB(address) val right = registers.getUB(i.reg1!!) memory.setUB(address, left or right) } - VmDataType.WORD -> { + IRDataType.WORD -> { val left = memory.getUW(address) val right = registers.getUW(i.reg1!!) memory.setUW(address, left or right) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1476,18 +1478,18 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsXORR(i: IRInstruction) { val (left: UInt, right: UInt) = getLogicalOperandsU(i) when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (left xor right).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (left xor right).toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, (left xor right).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (left xor right).toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsXOR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) xor i.value!!.toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) xor i.value!!.toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!) xor i.value!!.toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!) xor i.value!!.toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1495,26 +1497,26 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsXORM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val left = memory.getUB(address) val right = registers.getUB(i.reg1!!) memory.setUB(address, left xor right) } - VmDataType.WORD -> { + IRDataType.WORD -> { val left = memory.getUW(address) val right = registers.getUW(i.reg1!!) memory.setUW(address, left xor right) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsINV(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!).inv()) - VmDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!).inv()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, registers.getUB(i.reg1!!).inv()) + IRDataType.WORD -> registers.setUW(i.reg1!!, registers.getUW(i.reg1!!).inv()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1522,9 +1524,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsINVM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> memory.setUB(address, memory.getUB(address).inv()) - VmDataType.WORD -> memory.setUW(address, memory.getUW(address).inv()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> memory.setUB(address, memory.getUB(address).inv()) + IRDataType.WORD -> memory.setUW(address, memory.getUW(address).inv()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1533,9 +1535,9 @@ class VirtualMachine(irProgram: IRProgram) { val (left: Int, right: Int) = getLogicalOperandsS(i) statusCarry = (left and 1)!=0 when(i.type!!) { - VmDataType.BYTE -> registers.setSB(i.reg1!!, (left shr right).toByte()) - VmDataType.WORD -> registers.setSW(i.reg1!!, (left shr right).toShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setSB(i.reg1!!, (left shr right).toByte()) + IRDataType.WORD -> registers.setSW(i.reg1!!, (left shr right).toShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1544,34 +1546,34 @@ class VirtualMachine(irProgram: IRProgram) { val address = i.value!! val operand = registers.getUB(i.reg1!!).toInt() when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val memvalue = memory.getSB(address).toInt() statusCarry = (memvalue and 1)!=0 memory.setSB(address, (memvalue shr operand).toByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val memvalue = memory.getSW(address).toInt() statusCarry = (memvalue and 1)!=0 memory.setSW(address, (memvalue shr operand).toShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsASR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = registers.getSB(i.reg1!!).toInt() statusCarry = (value and 1)!=0 registers.setSB(i.reg1!!, (value shr 1).toByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = registers.getSW(i.reg1!!).toInt() statusCarry = (value and 1)!=0 registers.setSW(i.reg1!!, (value shr 1).toShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1579,17 +1581,17 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsASRM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = memory.getSB(address).toInt() statusCarry = (value and 1)!=0 memory.setSB(address, (value shr 1).toByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = memory.getSW(address).toInt() statusCarry = (value and 1)!=0 memory.setSW(address, (value shr 1).toShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1598,9 +1600,9 @@ class VirtualMachine(irProgram: IRProgram) { val (left: UInt, right: UInt) = getLogicalOperandsU(i) statusCarry = (left and 1u)!=0u when(i.type!!) { - VmDataType.BYTE -> registers.setUB(i.reg1!!, (left shr right.toInt()).toUByte()) - VmDataType.WORD -> registers.setUW(i.reg1!!, (left shr right.toInt()).toUShort()) - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.BYTE -> registers.setUB(i.reg1!!, (left shr right.toInt()).toUByte()) + IRDataType.WORD -> registers.setUW(i.reg1!!, (left shr right.toInt()).toUShort()) + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1609,34 +1611,34 @@ class VirtualMachine(irProgram: IRProgram) { val address = i.value!! val operand = registers.getUB(i.reg1!!).toInt() when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val memvalue = memory.getUB(address).toInt() statusCarry = (memvalue and 1)!=0 memory.setUB(address, (memvalue shr operand).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val memvalue = memory.getUW(address).toInt() statusCarry = (memvalue and 1)!=0 memory.setUW(address, (memvalue shr operand).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsLSR(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = registers.getUB(i.reg1!!).toInt() statusCarry = (value and 1)!=0 registers.setUB(i.reg1!!, (value shr 1).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = registers.getUW(i.reg1!!).toInt() statusCarry = (value and 1)!=0 registers.setUW(i.reg1!!, (value shr 1).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1644,17 +1646,17 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsLSRM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = memory.getUB(address).toInt() statusCarry = (value and 1)!=0 memory.setUB(address, (value shr 1).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = memory.getUW(address).toInt() statusCarry = (value and 1)!=0 memory.setUW(address, (value shr 1).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1662,15 +1664,15 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsLSLN(i: IRInstruction) { val (left: UInt, right: UInt) = getLogicalOperandsU(i) when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { statusCarry = (left and 0x80u)!=0u registers.setUB(i.reg1!!, (left shl right.toInt()).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { statusCarry = (left and 0x8000u)!=0u registers.setUW(i.reg1!!, (left shl right.toInt()).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1679,34 +1681,34 @@ class VirtualMachine(irProgram: IRProgram) { val address = i.value!! val operand = registers.getUB(i.reg1!!).toInt() when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val memvalue = memory.getUB(address).toInt() statusCarry = (memvalue and 0x80)!=0 memory.setUB(address, (memvalue shl operand).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val memvalue = memory.getUW(address).toInt() statusCarry = (memvalue and 0x8000)!=0 memory.setUW(address, (memvalue shl operand).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsLSL(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = registers.getUB(i.reg1!!).toInt() statusCarry = (value and 0x80)!=0 registers.setUB(i.reg1!!, (value shl 1).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = registers.getUW(i.reg1!!).toInt() statusCarry = (value and 0x8000)!=0 registers.setUW(i.reg1!!, (value shl 1).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1714,17 +1716,17 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsLSLM(i: IRInstruction) { val address = i.value!! when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = memory.getUB(address).toInt() statusCarry = (value and 0x80)!=0 memory.setUB(address, (value shl 1).toUByte()) } - VmDataType.WORD -> { + IRDataType.WORD -> { val value = memory.getUW(address).toInt() statusCarry = (value and 0x8000)!=0 memory.setUW(address, (value shl 1).toUShort()) } - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -1732,7 +1734,7 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsROR(i: IRInstruction, useCarry: Boolean) { val newStatusCarry: Boolean when (i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val orig = registers.getUB(i.reg1!!) newStatusCarry = (orig.toInt() and 1) != 0 val rotated: UByte = if (useCarry) { @@ -1742,7 +1744,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateRight(1) registers.setUB(i.reg1!!, rotated) } - VmDataType.WORD -> { + IRDataType.WORD -> { val orig = registers.getUW(i.reg1!!) newStatusCarry = (orig.toInt() and 1) != 0 val rotated: UShort = if (useCarry) { @@ -1752,7 +1754,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateRight(1) registers.setUW(i.reg1!!, rotated) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { throw IllegalArgumentException("can't ROR a float") } } @@ -1764,7 +1766,7 @@ class VirtualMachine(irProgram: IRProgram) { val newStatusCarry: Boolean val address = i.value!! when (i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val orig = memory.getUB(address) newStatusCarry = (orig.toInt() and 1) != 0 val rotated: UByte = if (useCarry) { @@ -1774,7 +1776,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateRight(1) memory.setUB(address, rotated) } - VmDataType.WORD -> { + IRDataType.WORD -> { val orig = memory.getUW(address) newStatusCarry = (orig.toInt() and 1) != 0 val rotated: UShort = if (useCarry) { @@ -1784,7 +1786,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateRight(1) memory.setUW(address, rotated) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { throw IllegalArgumentException("can't ROR a float") } } @@ -1795,7 +1797,7 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsROL(i: IRInstruction, useCarry: Boolean) { val newStatusCarry: Boolean when (i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val orig = registers.getUB(i.reg1!!) newStatusCarry = (orig.toInt() and 0x80) != 0 val rotated: UByte = if (useCarry) { @@ -1805,7 +1807,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateLeft(1) registers.setUB(i.reg1!!, rotated) } - VmDataType.WORD -> { + IRDataType.WORD -> { val orig = registers.getUW(i.reg1!!) newStatusCarry = (orig.toInt() and 0x8000) != 0 val rotated: UShort = if (useCarry) { @@ -1815,7 +1817,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateLeft(1) registers.setUW(i.reg1!!, rotated) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { throw IllegalArgumentException("can't ROL a float") } } @@ -1827,7 +1829,7 @@ class VirtualMachine(irProgram: IRProgram) { val address = i.value!! val newStatusCarry: Boolean when (i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val orig = memory.getUB(address) newStatusCarry = (orig.toInt() and 0x80) != 0 val rotated: UByte = if (useCarry) { @@ -1837,7 +1839,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateLeft(1) memory.setUB(address, rotated) } - VmDataType.WORD -> { + IRDataType.WORD -> { val orig = memory.getUW(address) newStatusCarry = (orig.toInt() and 0x8000) != 0 val rotated: UShort = if (useCarry) { @@ -1847,7 +1849,7 @@ class VirtualMachine(irProgram: IRProgram) { orig.rotateLeft(1) memory.setUW(address, rotated) } - VmDataType.FLOAT -> { + IRDataType.FLOAT -> { throw IllegalArgumentException("can't ROL a float") } } @@ -1857,26 +1859,26 @@ class VirtualMachine(irProgram: IRProgram) { private fun InsMSIG(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val value = registers.getUW(i.reg2!!) val newValue = value.toInt() ushr 8 registers.setUB(i.reg1!!, newValue.toUByte()) } - VmDataType.WORD -> throw IllegalArgumentException("msig.w not yet supported, requires 32-bits registers") - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.WORD -> throw IllegalArgumentException("msig.w not yet supported, requires 32-bits registers") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } private fun InsCONCAT(i: IRInstruction) { when(i.type!!) { - VmDataType.BYTE -> { + IRDataType.BYTE -> { val lsb = registers.getUB(i.reg1!!) val msb = registers.getUB(i.reg2!!) registers.setUW(i.reg1!!, ((msb.toInt() shl 8) or lsb.toInt()).toUShort()) } - VmDataType.WORD -> throw IllegalArgumentException("concat.w not yet supported, requires 32-bits registers") - VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") + IRDataType.WORD -> throw IllegalArgumentException("concat.w not yet supported, requires 32-bits registers") + IRDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ } @@ -2004,9 +2006,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun getBranchOperands(i: IRInstruction): Pair { return when(i.type) { - VmDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) - VmDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) + IRDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt()) + IRDataType.FLOAT -> { throw IllegalArgumentException("can't use float here") } null -> throw IllegalArgumentException("need type for branch instruction") @@ -2015,9 +2017,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun getBranchOperandsU(i: IRInstruction): Pair { return when(i.type) { - VmDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt()) - VmDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt()) + IRDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt()) + IRDataType.FLOAT -> { throw IllegalArgumentException("can't use float here") } null -> throw IllegalArgumentException("need type for branch instruction") @@ -2026,9 +2028,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun getLogicalOperandsU(i: IRInstruction): Pair { return when(i.type) { - VmDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt()) - VmDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> Pair(registers.getUB(i.reg1!!).toUInt(), registers.getUB(i.reg2!!).toUInt()) + IRDataType.WORD -> Pair(registers.getUW(i.reg1!!).toUInt(), registers.getUW(i.reg2!!).toUInt()) + IRDataType.FLOAT -> { throw IllegalArgumentException("can't use float here") } null -> throw IllegalArgumentException("need type for logical instruction") @@ -2037,9 +2039,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun getLogicalOperandsS(i: IRInstruction): Pair { return when(i.type) { - VmDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) - VmDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> Pair(registers.getSB(i.reg1!!).toInt(), registers.getSB(i.reg2!!).toInt()) + IRDataType.WORD -> Pair(registers.getSW(i.reg1!!).toInt(), registers.getSW(i.reg2!!).toInt()) + IRDataType.FLOAT -> { throw IllegalArgumentException("can't use float here") } null -> throw IllegalArgumentException("need type for logical instruction") @@ -2048,9 +2050,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun getSetOnConditionOperands(ins: IRInstruction): Pair { return when(ins.type) { - VmDataType.BYTE -> Pair(registers.getSB(ins.reg1!!).toInt(), registers.getSB(ins.reg2!!).toInt()) - VmDataType.WORD -> Pair(registers.getSW(ins.reg1!!).toInt(), registers.getSW(ins.reg2!!).toInt()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> Pair(registers.getSB(ins.reg1!!).toInt(), registers.getSB(ins.reg2!!).toInt()) + IRDataType.WORD -> Pair(registers.getSW(ins.reg1!!).toInt(), registers.getSW(ins.reg2!!).toInt()) + IRDataType.FLOAT -> { throw IllegalArgumentException("can't use float here") } null -> throw IllegalArgumentException("need type for branch instruction") @@ -2059,9 +2061,9 @@ class VirtualMachine(irProgram: IRProgram) { private fun getSetOnConditionOperandsU(ins: IRInstruction): Pair { return when(ins.type) { - VmDataType.BYTE -> Pair(registers.getUB(ins.reg1!!).toUInt(), registers.getUB(ins.reg2!!).toUInt()) - VmDataType.WORD -> Pair(registers.getUW(ins.reg1!!).toUInt(), registers.getUW(ins.reg2!!).toUInt()) - VmDataType.FLOAT -> { + IRDataType.BYTE -> Pair(registers.getUB(ins.reg1!!).toUInt(), registers.getUB(ins.reg2!!).toUInt()) + IRDataType.WORD -> Pair(registers.getUW(ins.reg1!!).toUInt(), registers.getUW(ins.reg2!!).toUInt()) + IRDataType.FLOAT -> { throw IllegalArgumentException("can't use float here") } null -> throw IllegalArgumentException("need type for branch instruction") diff --git a/virtualmachine/test/TestVm.kt b/virtualmachine/test/TestVm.kt index 80ea104c1..bbd5413d3 100644 --- a/virtualmachine/test/TestVm.kt +++ b/virtualmachine/test/TestVm.kt @@ -44,8 +44,8 @@ class TestVm: FunSpec( { val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY) val code = IRCodeChunk(Position.DUMMY) code += IRInstruction(Opcode.NOP) - code += IRInstruction(Opcode.LOAD, VmDataType.WORD, reg1=1, value=12345) - code += IRInstruction(Opcode.STOREM, VmDataType.WORD, reg1=1, value=1000) + code += IRInstruction(Opcode.LOAD, IRDataType.WORD, reg1=1, value=12345) + code += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1=1, value=1000) code += IRInstruction(Opcode.RETURN) startSub += code block += startSub @@ -107,6 +107,9 @@ class TestVm: FunSpec( { + + +