diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 207eba9ce..ba48af3b8 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -119,7 +119,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, "cmp" -> funcCmp(fcall) "callfar" -> funcCallFar(fcall) "callrom" -> funcCallRom(fcall) - "syscall", "syscall1", "syscall2", "syscall3" -> throw AssemblyError("6502 assembly target doesn't use syscall function interface") + "syscall", "syscall1", "syscall2", "syscall3", "syscall1fp" -> throw AssemblyError("6502 assembly target doesn't use syscall function interface") else -> throw AssemblyError("missing asmgen for builtin func ${func.name}") } } diff --git a/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt b/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt index 72584b42d..09d8537be 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/AssemblyProgram.kt @@ -71,6 +71,19 @@ internal class VmCodeInstruction( val ins = Instruction(opcode, type, reg1, reg2, reg3, fpReg1, fpReg2, fpReg3, value, fpValue, symbol) init { + if(reg1!=null && (reg1<0 || reg1>65536)) + throw IllegalArgumentException("reg1 out of bounds") + if(reg2!=null && (reg2<0 || reg2>65536)) + throw IllegalArgumentException("reg2 out of bounds") + if(reg3!=null && (reg3<0 || reg3>65536)) + throw IllegalArgumentException("reg3 out of bounds") + if(fpReg1!=null && (fpReg1<0 || fpReg1>65536)) + throw IllegalArgumentException("fpReg1 out of bounds") + if(fpReg2!=null && (fpReg2<0 || fpReg2>65536)) + throw IllegalArgumentException("fpReg2 out of bounds") + if(fpReg3!=null && (fpReg3<0 || fpReg3>65536)) + throw IllegalArgumentException("fpReg3 out of bounds") + if(value!=null && opcode !in OpcodesWithAddress) { when (type) { VmDataType.BYTE -> { diff --git a/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt index 4db8a6bef..514904004 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/BuiltinFuncGen.kt @@ -36,6 +36,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: "syscall1" -> funcSyscall1(call) "syscall2" -> funcSyscall2(call) "syscall3" -> funcSyscall3(call) + "syscall1fp" -> funcSyscall1fp(call) "msb" -> funcMsb(call, resultRegister) "lsb" -> funcLsb(call, resultRegister) "memory" -> funcMemory(call, resultRegister) @@ -60,8 +61,8 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: val code = VmCodeChunk() val leftRegister = codeGen.vmRegisters.nextFree() val rightRegister = codeGen.vmRegisters.nextFree() - code += exprGen.translateExpression(call.args[0], leftRegister, 99999) - code += exprGen.translateExpression(call.args[1], rightRegister, 99999) + code += exprGen.translateExpression(call.args[0], leftRegister, -1) + code += exprGen.translateExpression(call.args[1], rightRegister, -1) code += VmCodeInstruction(Opcode.CMP, codeGen.vmType(call.args[0].type), reg1=leftRegister, reg2=rightRegister) return code } @@ -80,7 +81,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: else -> throw IllegalArgumentException("weird type") } val code = VmCodeChunk() - code += exprGen.translateExpression(call.args[0], 0, 99999) + code += exprGen.translateExpression(call.args[0], 0, -1) code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal) if(resultRegister!=0) @@ -102,7 +103,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: else -> throw IllegalArgumentException("weird type") } val code = VmCodeChunk() - code += exprGen.translateExpression(call.args[0], 0, 99999) + code += exprGen.translateExpression(call.args[0], 0, -1) code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) code += VmCodeInstruction(Opcode.SYSCALL, value=syscall.ordinal) if(resultRegister!=0) @@ -114,7 +115,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: val code = VmCodeChunk() val sourceDt = call.args.single().type if(sourceDt!=DataType.UWORD) { - code += exprGen.translateExpression(call.args[0], resultRegister, 99999) + code += exprGen.translateExpression(call.args[0], resultRegister, -1) when (sourceDt) { DataType.UBYTE -> { code += VmCodeInstruction(Opcode.EXT, VmDataType.BYTE, reg1=resultRegister) @@ -146,14 +147,14 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, 99999) + code += exprGen.translateExpression(call.args.single(), 0, -1) code += VmCodeInstruction(Opcode.SGN, codeGen.vmType(call.type), reg1=resultRegister, reg2=0) return code } private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, 99999) + code += exprGen.translateExpression(call.args.single(), 0, -1) code += VmCodeInstruction(Opcode.SQRT, VmDataType.WORD, reg1=resultRegister, reg2=0) return code } @@ -174,14 +175,14 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: private fun funcPush(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, 99999) + code += exprGen.translateExpression(call.args.single(), 0, -1) code += VmCodeInstruction(Opcode.PUSH, VmDataType.BYTE, reg1=0) return code } private fun funcPushw(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), 0, 99999) + code += exprGen.translateExpression(call.args.single(), 0, -1) code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1=0) return code } @@ -192,8 +193,8 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: val leftReg = codeGen.vmRegisters.nextFree() val rightReg = codeGen.vmRegisters.nextFree() val code = VmCodeChunk() - code += exprGen.translateExpression(left, leftReg, 99999) - code += exprGen.translateExpression(right, rightReg, 99999) + code += exprGen.translateExpression(left, leftReg, -1) + code += exprGen.translateExpression(right, rightReg, -1) code += assignRegisterTo(left, rightReg) code += assignRegisterTo(right, leftReg) return code @@ -210,7 +211,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: else -> throw IllegalArgumentException("weird type to reverse") } val code = VmCodeChunk() - code += exprGen.translateExpression(call.args[0], 0, 99999) + code += exprGen.translateExpression(call.args[0], 0, -1) code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) code += VmCodeInstruction(Opcode.SYSCALL, value=sortSyscall.ordinal) return code @@ -230,7 +231,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: else -> throw IllegalArgumentException("weird type to sort") } val code = VmCodeChunk() - code += exprGen.translateExpression(call.args[0], 0, 99999) + code += exprGen.translateExpression(call.args[0], 0, -1) code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length) code += VmCodeInstruction(Opcode.SYSCALL, value=sortSyscall.ordinal) return code @@ -240,8 +241,8 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: val msbReg = codeGen.vmRegisters.nextFree() val lsbReg = codeGen.vmRegisters.nextFree() val code = VmCodeChunk() - code += exprGen.translateExpression(call.args[0], msbReg, 99999) - code += exprGen.translateExpression(call.args[1], lsbReg, 99999) + code += exprGen.translateExpression(call.args[0], msbReg, -1) + code += exprGen.translateExpression(call.args[1], lsbReg, -1) code += VmCodeInstruction(Opcode.CONCAT, VmDataType.BYTE, reg1=resultRegister, reg2=msbReg, reg3=lsbReg) return code } @@ -251,12 +252,12 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: val valueReg = codeGen.vmRegisters.nextFree() if(call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() - code += exprGen.translateExpression(call.args[1], valueReg, 99999) + code += exprGen.translateExpression(call.args[1], valueReg, -1) code += VmCodeInstruction(Opcode.STOREM, VmDataType.WORD, reg1 = valueReg, value=address) } else { val addressReg = codeGen.vmRegisters.nextFree() - code += exprGen.translateExpression(call.args[0], addressReg, 99999) - code += exprGen.translateExpression(call.args[1], valueReg, 99999) + code += exprGen.translateExpression(call.args[0], addressReg, -1) + code += exprGen.translateExpression(call.args[1], valueReg, -1) code += VmCodeInstruction(Opcode.STOREI, VmDataType.WORD, reg1 = valueReg, reg2 = addressReg) } return code @@ -267,12 +268,12 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: val valueReg = codeGen.vmRegisters.nextFree() if(call.args[0] is PtNumber) { val address = (call.args[0] as PtNumber).number.toInt() - code += exprGen.translateExpression(call.args[1], valueReg, 99999) + code += exprGen.translateExpression(call.args[1], valueReg, -1) code += VmCodeInstruction(Opcode.STOREM, VmDataType.BYTE, reg1 = valueReg, value=address) } else { val addressReg = codeGen.vmRegisters.nextFree() - code += exprGen.translateExpression(call.args[0], addressReg, 99999) - code += exprGen.translateExpression(call.args[1], valueReg, 99999) + code += exprGen.translateExpression(call.args[0], addressReg, -1) + code += exprGen.translateExpression(call.args[1], valueReg, -1) code += VmCodeInstruction(Opcode.STOREI, VmDataType.BYTE, reg1 = valueReg, reg2 = addressReg) } return code @@ -285,7 +286,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: code += VmCodeInstruction(Opcode.LOADM, VmDataType.WORD, reg1 = resultRegister, value = address) } else { val addressReg = codeGen.vmRegisters.nextFree() - code += exprGen.translateExpression(call.args.single(), addressReg, 99999) + code += exprGen.translateExpression(call.args.single(), addressReg, -1) code += VmCodeInstruction(Opcode.LOADI, VmDataType.WORD, reg1 = resultRegister, reg2 = addressReg) } return code @@ -298,7 +299,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: code += VmCodeInstruction(Opcode.LOADM, VmDataType.BYTE, reg1 = resultRegister, value = address) } else { val addressReg = codeGen.vmRegisters.nextFree() - code += exprGen.translateExpression(call.args.single(), addressReg, 99999) + code += exprGen.translateExpression(call.args.single(), addressReg, -1) code += VmCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1 = resultRegister, reg2 = addressReg) } return code @@ -336,14 +337,14 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: private fun funcLsb(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), resultRegister, 99999) + code += exprGen.translateExpression(call.args.single(), resultRegister, -1) // 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 funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += exprGen.translateExpression(call.args.single(), resultRegister, 99999) + code += exprGen.translateExpression(call.args.single(), resultRegister, -1) code += VmCodeInstruction(Opcode.MSIG, VmDataType.BYTE, reg1 = resultRegister, reg2=resultRegister) // note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here. return code @@ -359,7 +360,15 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: private fun funcSyscall1(call: PtBuiltinFunctionCall): VmCodeChunk { val code = VmCodeChunk() val callNr = (call.args[0] as PtNumber).number.toInt() - code += exprGen.translateExpression(call.args[1], 0, 99999) + code += exprGen.translateExpression(call.args[1], 0, -1) + code += VmCodeInstruction(Opcode.SYSCALL, value=callNr) + return code + } + + private fun funcSyscall1fp(call: PtBuiltinFunctionCall): VmCodeChunk { + val code = VmCodeChunk() + val callNr = (call.args[0] as PtNumber).number.toInt() + code += exprGen.translateExpression(call.args[1], -1, 0) code += VmCodeInstruction(Opcode.SYSCALL, value=callNr) return code } @@ -371,8 +380,8 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: codeGen.vmRegisters.nextFree() } val callNr = (call.args[0] as PtNumber).number.toInt() - code += exprGen.translateExpression(call.args[1], 0, 99999) - code += exprGen.translateExpression(call.args[2], 1, 99999) + code += exprGen.translateExpression(call.args[1], 0, -1) + code += exprGen.translateExpression(call.args[2], 1, -1) code += VmCodeInstruction(Opcode.SYSCALL, value=callNr) code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 1) return code @@ -386,9 +395,9 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: codeGen.vmRegisters.nextFree() } val callNr = (call.args[0] as PtNumber).number.toInt() - code += exprGen.translateExpression(call.args[1], 0, 99999) - code += exprGen.translateExpression(call.args[2], 1, 99999) - code += exprGen.translateExpression(call.args[3], 2, 99999) + code += exprGen.translateExpression(call.args[1], 0, -1) + code += exprGen.translateExpression(call.args[2], 1, -1) + code += exprGen.translateExpression(call.args[3], 2, -1) code += VmCodeInstruction(Opcode.SYSCALL, value=callNr) code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 2) code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 1) @@ -398,7 +407,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen: private fun funcRolRor2(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk { val vmDt = codeGen.vmType(call.args[0].type) val code = VmCodeChunk() - code += exprGen.translateExpression(call.args[0], resultRegister, 99999) + code += exprGen.translateExpression(call.args[0], resultRegister, -1) code += VmCodeInstruction(opcode, vmDt, reg1=resultRegister) code += assignRegisterTo(call.args[0], resultRegister) return code diff --git a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt index e26fbab30..ab35e7136 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt @@ -78,7 +78,7 @@ class CodeGen(internal val program: PtProgram, is PtAssignment -> translate(node) is PtNodeGroup -> translateGroup(node.children) is PtBuiltinFunctionCall -> translateBuiltinFunc(node, 0) - is PtFunctionCall -> expressionEval.translate(node, 0) + is PtFunctionCall -> expressionEval.translate(node, 0, 0) is PtNop -> VmCodeChunk() is PtReturn -> translate(node) is PtJump -> translate(node) @@ -151,7 +151,7 @@ class CodeGen(internal val program: PtProgram, val valueReg = vmRegisters.nextFree() val choiceReg = vmRegisters.nextFree() val valueDt = vmType(whenStmt.value.type) - code += expressionEval.translateExpression(whenStmt.value, valueReg, 99999) + code += expressionEval.translateExpression(whenStmt.value, valueReg, -1) val choices = whenStmt.choices.children.map {it as PtWhenChoice } val endLabel = createLabelName() for (choice in choices) { @@ -249,8 +249,8 @@ class CodeGen(internal val program: PtProgram, val loopLabel = createLabelName() val code = VmCodeChunk() - code += expressionEval.translateExpression(iterable.to, endvalueReg, 99999) - code += expressionEval.translateExpression(iterable.from, indexReg, 99999) + code += expressionEval.translateExpression(iterable.to, endvalueReg, -1) + code += expressionEval.translateExpression(iterable.from, indexReg, -1) code += VmCodeInstruction(Opcode.STOREM, loopvarDt, reg1=indexReg, value=loopvarAddress) code += VmCodeLabel(loopLabel) code += translateNode(forLoop.statements) @@ -458,7 +458,7 @@ class CodeGen(internal val program: PtProgram, val conditionReg = vmRegisters.nextFree() val vmDt = vmType(condition.type) val code = VmCodeChunk() - code += expressionEval.translateExpression(condition, conditionReg, 99999) + code += expressionEval.translateExpression(condition, conditionReg, -1) if(ifElse.elseScope.children.isNotEmpty()) { // if and else parts val elseLabel = createLabelName() @@ -504,7 +504,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1 = resultReg, value=address) } else { val addressReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(memory.address, addressReg, 99999) + code += expressionEval.translateExpression(memory.address, addressReg, -1) code += VmCodeInstruction(Opcode.LOADI, vmDt, reg1 = resultReg, reg2 = addressReg) code += VmCodeInstruction(operation, vmDt, reg1 = resultReg) code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1 = resultReg, reg2 = addressReg) @@ -524,7 +524,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(memOp, vmDt, value=variableAddr) } else { val indexReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(array.index, indexReg, 99999) + code += expressionEval.translateExpression(array.index, indexReg, -1) code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultReg, reg2=indexReg, value=variableAddr) code += VmCodeInstruction(operation, vmDt, reg1=resultReg) code += VmCodeInstruction(Opcode.STOREX, vmDt, reg1=resultReg, reg2=indexReg, value=variableAddr) @@ -548,7 +548,7 @@ class CodeGen(internal val program: PtProgram, val code = VmCodeChunk() val counterReg = vmRegisters.nextFree() val vmDt = vmType(repeat.count.type) - code += expressionEval.translateExpression(repeat.count, counterReg, 99999) + code += expressionEval.translateExpression(repeat.count, counterReg, -1) val repeatLabel = createLabelName() code += VmCodeLabel(repeatLabel) code += translateNode(repeat.statements) @@ -582,20 +582,30 @@ class CodeGen(internal val program: PtProgram, if(assignment.target.children.single() is PtMachineRegister) throw AssemblyError("assigning to a register should be done by just evaluating the expression into resultregister") val code = VmCodeChunk() - val resultRegister = if(assignment.value is PtMachineRegister) { - (assignment.value as PtMachineRegister).register - } else { - val reg = vmRegisters.nextFree() - code += expressionEval.translateExpression(assignment.value, reg, 99999) - reg - } val ident = assignment.target.identifier val memory = assignment.target.memory val array = assignment.target.array val vmDt = vmType(assignment.value.type) + var resultRegister = -1 + var resultFpRegister = -1 + if(vmDt==VmDataType.FLOAT) { + resultFpRegister = vmRegisters.nextFreeFloat() + code += expressionEval.translateExpression(assignment.value, -1, resultFpRegister) + } else { + resultRegister = if (assignment.value is PtMachineRegister) { + (assignment.value as PtMachineRegister).register + } else { + val reg = vmRegisters.nextFree() + code += expressionEval.translateExpression(assignment.value, reg, -1) + reg + } + } if(ident!=null) { val address = allocations.get(ident.targetName) - code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=address) + code += if(vmDt==VmDataType.FLOAT) + VmCodeInstruction(Opcode.STOREM, vmDt, fpReg1=resultFpRegister, value=address) + else + VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=address) } else if(array!=null) { val variable = array.variable.targetName @@ -608,7 +618,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.STOREM, vmDtArrayIdx, reg1 = resultRegister, value=variableAddr) } else { val indexReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(array.index, indexReg, 99999) + code += expressionEval.translateExpression(array.index, indexReg, -1) code += VmCodeInstruction(Opcode.STOREX, vmDtArrayIdx, reg1 = resultRegister, reg2=indexReg, value=variableAddr) } } @@ -618,7 +628,7 @@ class CodeGen(internal val program: PtProgram, code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=resultRegister, value=(memory.address as PtNumber).number.toInt()) } else { val addressReg = vmRegisters.nextFree() - code += expressionEval.translateExpression(memory.address, addressReg, 99999) + code += expressionEval.translateExpression(memory.address, addressReg, -1) code += VmCodeInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg) } } @@ -631,8 +641,11 @@ class CodeGen(internal val program: PtProgram, val code = VmCodeChunk() val value = ret.value if(value!=null) { - // Call Convention: return value is always returned in r0 - code += expressionEval.translateExpression(value, 0, 99999) + // Call Convention: return value is always returned in r0 (or fr0 if float) + code += if(value.type==DataType.FLOAT) + expressionEval.translateExpression(value, -1, 0) + else + expressionEval.translateExpression(value, 0, -1) } code += VmCodeInstruction(Opcode.RETURN) return code diff --git a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt index 6d505f66c..759ed38c5 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt @@ -26,13 +26,19 @@ internal class ExpressionGen(private val codeGen: CodeGen) { } is PtNumber -> { val vmDt = codeGen.vmType(expr.type) - code += VmCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=expr.number.toInt()) + code += if(vmDt==VmDataType.FLOAT) + VmCodeInstruction(Opcode.LOAD, vmDt, fpReg1 = resultFpRegister, fpValue = expr.number.toFloat()) + else + VmCodeInstruction(Opcode.LOAD, vmDt, reg1=resultRegister, value=expr.number.toInt()) } is PtIdentifier -> { val vmDt = codeGen.vmType(expr.type) val mem = codeGen.allocations.get(expr.targetName) code += if (expr.type in PassByValueDatatypes) { - VmCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, value = mem) + if(vmDt==VmDataType.FLOAT) + VmCodeInstruction(Opcode.LOADM, vmDt, fpReg1 = resultFpRegister, value = mem) + else + VmCodeInstruction(Opcode.LOADM, vmDt, reg1 = resultRegister, value = mem) } else { // for strings and arrays etc., load the *address* of the value instead VmCodeInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, value = mem) @@ -49,7 +55,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { code += VmCodeInstruction(Opcode.LOADM, VmDataType.BYTE, reg1=resultRegister, value = address) } else { val addressRegister = codeGen.vmRegisters.nextFree() - code += translateExpression(expr.address, addressRegister, 99999) + code += translateExpression(expr.address, addressRegister, -1) code += VmCodeInstruction(Opcode.LOADI, VmDataType.BYTE, reg1=resultRegister, reg2=addressRegister) } } @@ -58,8 +64,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { is PtArrayIndexer -> code += translate(expr, resultRegister) is PtBinaryExpression -> code += translate(expr, resultRegister) is PtBuiltinFunctionCall -> code += codeGen.translateBuiltinFunc(expr, resultRegister) - is PtFunctionCall -> code += translate(expr, resultRegister) - is PtContainmentCheck -> code += translate(expr, resultRegister) + is PtFunctionCall -> code += translate(expr, resultRegister, resultFpRegister) + is PtContainmentCheck -> code += translate(expr, resultRegister, resultFpRegister) is PtPipe -> code += translate(expr, resultRegister) is PtRange, is PtArray, @@ -91,7 +97,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { } val code = VmCodeChunk() - code += translateExpression(segments[0], valueReg, 99999) + code += translateExpression(segments[0], valueReg, -1) for (segment in segments.subList(1, segments.size-1)) { val sourceReg = valueReg val sourceDt = valueDt @@ -100,37 +106,37 @@ internal class ExpressionGen(private val codeGen: CodeGen) { valueReg = codeGen.vmRegisters.nextFree() } val segmentWithImplicitArgument = addImplicitArgToSegment(segment, sourceReg, sourceDt) - code += translateExpression(segmentWithImplicitArgument, valueReg, 99999) + code += translateExpression(segmentWithImplicitArgument, valueReg, -1) } val segWithArg = addImplicitArgToSegment(segments.last(), valueReg, valueDt) - code += translateExpression(segWithArg, resultRegister, 99999) + code += translateExpression(segWithArg, resultRegister, -1) return code } - private fun translate(check: PtContainmentCheck, resultRegister: Int): VmCodeChunk { + private fun translate(check: PtContainmentCheck, resultRegister: Int, resultFpRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += translateExpression(check.element, resultRegister, 99999) // load the element to check in resultRegister + code += translateExpression(check.element, resultRegister, -1) // load the element to check in resultRegister val iterable = codeGen.symbolTable.flat.getValue(check.iterable.targetName) as StStaticVariable when(iterable.dt) { DataType.STR -> { val call = PtFunctionCall(listOf("prog8_lib", "string_contains"), false, DataType.UBYTE, check.position) call.children.add(check.element) call.children.add(check.iterable) - code += translate(call, resultRegister) + code += translate(call, resultRegister, resultFpRegister) } DataType.ARRAY_UB, DataType.ARRAY_B -> { val call = PtFunctionCall(listOf("prog8_lib", "bytearray_contains"), false, DataType.UBYTE, check.position) call.children.add(check.element) call.children.add(check.iterable) call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position)) - code += translate(call, resultRegister) + code += translate(call, resultRegister, resultFpRegister) } DataType.ARRAY_UW, DataType.ARRAY_W -> { val call = PtFunctionCall(listOf("prog8_lib", "wordarray_contains"), false, DataType.UBYTE, check.position) call.children.add(check.element) call.children.add(check.iterable) call.children.add(PtNumber(DataType.UBYTE, iterable.length!!.toDouble(), iterable.position)) - code += translate(call, resultRegister) + code += translate(call, resultRegister, resultFpRegister) } DataType.ARRAY_F -> TODO("containment check in float-array") else -> throw AssemblyError("weird iterable dt ${iterable.dt} for ${check.iterable.targetName}") @@ -149,7 +155,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val memOffset = (arrayIx.index as PtNumber).number.toInt() * eltSize code += VmCodeInstruction(Opcode.LOADM, vmDt, reg1=resultRegister, value=arrayLocation+memOffset) } else { - code += translateExpression(arrayIx.index, idxReg, 99999) + code += translateExpression(arrayIx.index, idxReg, -1) if(eltSize>1) code += codeGen.multiplyByConst(VmDataType.BYTE, idxReg, eltSize) code += VmCodeInstruction(Opcode.LOADX, vmDt, reg1=resultRegister, reg2=idxReg, value = arrayLocation) @@ -159,7 +165,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { private fun translate(expr: PtPrefix, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - code += translateExpression(expr.value, resultRegister, 99999) + code += translateExpression(expr.value, resultRegister, -1) val vmDt = codeGen.vmType(expr.type) when(expr.operator) { "+" -> { } @@ -190,7 +196,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() if(cast.type==cast.value.type) return code - code += translateExpression(cast.value, resultRegister, 99999) + code += translateExpression(cast.value, resultRegister, -1) when(cast.type) { DataType.UBYTE -> { when(cast.value.type) { @@ -297,8 +303,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) val ins = if(signed) { if(greaterEquals) Opcode.SGES else Opcode.SGTS } else { @@ -318,8 +324,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) val ins = if(signed) { if(lessEquals) Opcode.SLES else Opcode.SLTS } else { @@ -333,8 +339,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) val opcode = if(notEquals) Opcode.SNE else Opcode.SEQ code += VmCodeInstruction(opcode, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code @@ -344,8 +350,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) val opc = if(signed) Opcode.ASRX else Opcode.LSRX code += VmCodeInstruction(opc, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code @@ -355,8 +361,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.LSLX, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code } @@ -365,8 +371,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.XOR, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code } @@ -375,8 +381,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.AND, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code } @@ -385,8 +391,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.OR, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code } @@ -395,8 +401,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.MOD, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) return code } @@ -405,14 +411,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val code = VmCodeChunk() val constFactorRight = binExpr.right as? PtNumber if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { - code += translateExpression(binExpr.left, resultRegister, 99999) + code += translateExpression(binExpr.left, resultRegister, -1) val factor = constFactorRight.number.toInt() code += codeGen.divideByConst(vmDt, resultRegister, factor) } else { val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) } return code @@ -423,18 +429,18 @@ internal class ExpressionGen(private val codeGen: CodeGen) { val constFactorLeft = binExpr.left as? PtNumber val constFactorRight = binExpr.right as? PtNumber if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) { - code += translateExpression(binExpr.right, resultRegister, 99999) + code += translateExpression(binExpr.right, resultRegister, -1) val factor = constFactorLeft.number.toInt() code += codeGen.multiplyByConst(vmDt, resultRegister, factor) } else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { - code += translateExpression(binExpr.left, resultRegister, 99999) + code += translateExpression(binExpr.left, resultRegister, -1) val factor = constFactorRight.number.toInt() code += codeGen.multiplyByConst(vmDt, resultRegister, factor) } else { val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) } return code @@ -443,14 +449,14 @@ internal class ExpressionGen(private val codeGen: CodeGen) { private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() if((binExpr.right as? PtNumber)?.number==1.0) { - code += translateExpression(binExpr.left, resultRegister, 99999) + code += translateExpression(binExpr.left, resultRegister, -1) code += VmCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister) } else { val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) } return code @@ -459,37 +465,51 @@ internal class ExpressionGen(private val codeGen: CodeGen) { private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() if((binExpr.left as? PtNumber)?.number==1.0) { - code += translateExpression(binExpr.right, resultRegister, 99999) + code += translateExpression(binExpr.right, resultRegister, -1) code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister) } else if((binExpr.right as? PtNumber)?.number==1.0) { - code += translateExpression(binExpr.left, resultRegister, 99999) + code += translateExpression(binExpr.left, resultRegister, -1) code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister) } else { val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, 99999) - code += translateExpression(binExpr.right, rightResultReg, 99999) + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) } return code } - fun translate(fcall: PtFunctionCall, resultRegister: Int): VmCodeChunk { + fun translate(fcall: PtFunctionCall, resultRegister: Int, resultFpRegister: Int): VmCodeChunk { val subroutine = codeGen.symbolTable.flat.getValue(fcall.functionName) as StSub val code = VmCodeChunk() for ((arg, parameter) in fcall.args.zip(subroutine.parameters)) { - val argReg = codeGen.vmRegisters.nextFree() - code += translateExpression(arg, argReg, 99999) - val vmDt = codeGen.vmType(parameter.type) - val mem = codeGen.allocations.get(fcall.functionName + parameter.name) - code += VmCodeInstruction(Opcode.STOREM, vmDt, reg1=argReg, value=mem) + val paramDt = codeGen.vmType(parameter.type) + if(paramDt==VmDataType.FLOAT) { + val argFpReg = codeGen.vmRegisters.nextFreeFloat() + code += translateExpression(arg, -1, argFpReg) + val mem = codeGen.allocations.get(fcall.functionName + parameter.name) + code += VmCodeInstruction(Opcode.STOREM, paramDt, fpReg1 = argFpReg, value = mem) + } else { + val argReg = codeGen.vmRegisters.nextFree() + code += translateExpression(arg, argReg, -1) + val mem = codeGen.allocations.get(fcall.functionName + parameter.name) + code += VmCodeInstruction(Opcode.STOREM, paramDt, reg1 = argReg, value = mem) + } } code += VmCodeInstruction(Opcode.CALL, symbol=fcall.functionName) - if(!fcall.void && resultRegister!=0) { - // Call convention: result value is in r0, so put it in the required register instead. - code += VmCodeInstruction(Opcode.LOADR, codeGen.vmType(fcall.type), reg1=resultRegister, reg2=0) + 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 += VmCodeInstruction(Opcode.LOADR, VmDataType.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 += VmCodeInstruction(Opcode.LOADR, codeGen.vmType(fcall.type), reg1 = resultRegister, reg2 = 0) + } } return code } diff --git a/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt b/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt index f16bb36c0..fdf767908 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt @@ -67,7 +67,7 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg } else -> throw InternalCompilerException("weird dt") } - mm.add(Pair(variable.scopedName, "${location.toHex()} $typeStr $value")) + mm.add(Pair(variable.scopedName, "$location $typeStr $value")) } return mm } diff --git a/compiler/res/prog8lib/virtual/floats.p8 b/compiler/res/prog8lib/virtual/floats.p8 index 145f7009d..e79616ff5 100644 --- a/compiler/res/prog8lib/virtual/floats.p8 +++ b/compiler/res/prog8lib/virtual/floats.p8 @@ -11,84 +11,84 @@ floats { sub print_f(float value) { ; ---- prints the floating point value (without a newline). - ; TODO + void syscall1fp(sys.SC_PRINTF, value) } sub pow(float value, float power) -> float { ; TODO - return 0.0 + return -42.42 } sub fabs(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub sin(float angle) -> float { ; TODO - return 0.0 + return -42.42 } sub cos(float angle) -> float { ; TODO - return 0.0 + return -42.42 } sub tan(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub atan(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub ln(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub log2(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub sqrt(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub rad(float angle) -> float { ; -- convert degrees to radians (d * pi / 180) ; TODO - return 0.0 + return -42.42 } sub deg(float angle) -> float { ; -- convert radians to degrees (d * (1/ pi * 180)) ; TODO - return 0.0 + return -42.42 } sub round(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub floor(float value) -> float { ; TODO - return 0.0 + return -42.42 } sub ceil(float value) -> float { ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 ; TODO - return 0.0 + return -42.42 } sub rndf() -> float { ; TODO - return 0.0 + return -42.42 } } diff --git a/compiler/res/prog8lib/virtual/syslib.p8 b/compiler/res/prog8lib/virtual/syslib.p8 index b04e3576d..f15c6a302 100644 --- a/compiler/res/prog8lib/virtual/syslib.p8 +++ b/compiler/res/prog8lib/virtual/syslib.p8 @@ -8,7 +8,7 @@ sys { const ubyte target = 255 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 8 = atari800XL, 255 = virtual - ; SYSCALLS + ; Syscalls table, taken from Syscall enumeration ; 0 = reset ; resets system ; 1 = exit ; stops program and returns statuscode from r0.w ; 2 = print_c ; print single character @@ -20,8 +20,8 @@ sys { ; 8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480 ; 9 = gfx_clear ; clear graphics window with shade in r0.b ; 10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness - ; 11 = rnd ; random BYTE - ; 12 = rndw ; random WORD + ; 11 = set_carry status flag + ; 12 = clear_carry status flag ; 13 = wait ; wait certain amount of jiffies (1/60 sec) ; 14 = waitvsync ; wait on vsync ; 15 = sort_ubyte array @@ -44,26 +44,23 @@ sys { ; 32 = all_word array ; 33 = reverse_bytes array ; 34 = reverse_words array - ; 35 = set_carry status flag - ; 36 = clear_carry status flag - + ; 35 = printf (float arg in fpReg0) const ubyte SC_RESET = 0 const ubyte SC_EXIT = 1 const ubyte SC_PRINT_C = 2 const ubyte SC_PRINT_S = 3 const ubyte SC_PRINT_U8 = 4 - const ubyte SC_PRINT_u16 = 5 + const ubyte SC_PRINT_U16 = 5 const ubyte SC_INPUT = 6 const ubyte SC_SLEEP = 7 const ubyte SC_GFX_ENABLE = 8 const ubyte SC_GFX_CLEAR = 9 const ubyte SC_GFX_PLOT = 10 - const ubyte SC_RND = 11 - const ubyte SC_RNDW = 12 + const ubyte SC_SET_CARRY = 11 + const ubyte SC_CLEAR_CARRY = 12 const ubyte SC_WAIT = 13 const ubyte SC_WAITVSYNC = 14 - const ubyte SC_SET_CARRY = 35 - const ubyte SC_CLEAR_CARRY = 36 + const ubyte SC_PRINTF = 35 sub reset_system() { diff --git a/compilerAst/src/prog8/compiler/BuiltinFunctions.kt b/compilerAst/src/prog8/compiler/BuiltinFunctions.kt index 12c6c9d44..918a6846a 100644 --- a/compilerAst/src/prog8/compiler/BuiltinFunctions.kt +++ b/compilerAst/src/prog8/compiler/BuiltinFunctions.kt @@ -125,6 +125,7 @@ private val functionSignatures: List = listOf( FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null), FSignature("syscall" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE))), DataType.UWORD, null), FSignature("syscall1" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD))), DataType.UWORD, null), + FSignature("syscall1fp" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.FLOAT))), DataType.FLOAT, null), FSignature("syscall2" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD)), FParam("arg2", arrayOf(DataType.UWORD))), DataType.UWORD, null), FSignature("syscall3" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD)), FParam("arg2", arrayOf(DataType.UWORD)), FParam("arg3", arrayOf(DataType.UWORD))), DataType.UWORD, null), ) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 2dfafd8d8..dc9a7a9b3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,8 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- vm: implement floating point +- vm: allow inline "asm" where the assembly is vm-code instead of 6502 -- then get rid of the syscall() functions in prog8 +- vm: implement missing floating point functions - pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls. - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type - make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment) diff --git a/examples/test.p8 b/examples/test.p8 index 9cd4dff0a..75bcbd4f9 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,6 +8,7 @@ main { sub start() { + txt.print("float tests: ") float f1 = 1.2345 float f2 = -9.99 float f3 diff --git a/virtualmachine/src/prog8/vm/Assembler.kt b/virtualmachine/src/prog8/vm/Assembler.kt index 4d85b601b..515780962 100644 --- a/virtualmachine/src/prog8/vm/Assembler.kt +++ b/virtualmachine/src/prog8/vm/Assembler.kt @@ -166,23 +166,18 @@ class Assembler { if (value < -32768 || value > 65535) throw IllegalArgumentException("value out of range for word: $value") } - VmDataType.FLOAT -> { - throw IllegalArgumentException("can't use float here") - } + VmDataType.FLOAT -> {} null -> {} } } var floatValue: Float? = null var intValue: Int? = null - if(type==VmDataType.FLOAT) - floatValue = value // TODO NOT ALWAYS CORRECT, SOMETIMES IT IS THE INT VALUE - else - intValue = value?.toInt() - if(!format.value && intValue!=null) - throw IllegalArgumentException("invalid int value for $line") - if(!format.fpValue && floatValue!=null) - throw IllegalArgumentException("invalid float value for $line") + if(format.value) + intValue = value!!.toInt() + if(format.fpValue) + floatValue = value!! + program.add(Instruction(opcode, type, reg1, reg2, reg3, fpReg1, fpReg2, fpReg3, value = intValue, fpValue = floatValue)) } } diff --git a/virtualmachine/src/prog8/vm/SysCalls.kt b/virtualmachine/src/prog8/vm/SysCalls.kt index 0af9f55c4..17daeb1e8 100644 --- a/virtualmachine/src/prog8/vm/SysCalls.kt +++ b/virtualmachine/src/prog8/vm/SysCalls.kt @@ -40,6 +40,7 @@ SYSCALLS: 32 = all_word array 33 = reverse_bytes array 34 = reverse_words array +35 = print_f (floating point value in fpReg0) */ enum class Syscall { @@ -77,7 +78,8 @@ enum class Syscall { ALL_BYTE, ALL_WORD, REVERSE_BYTES, - REVERSE_WORDS + REVERSE_WORDS, + PRINT_F } object SysCalls { @@ -297,6 +299,10 @@ object SysCalls { } Syscall.SET_CARRY -> vm.statusCarry = true Syscall.CLEAR_CARRY -> vm.statusCarry = false + Syscall.PRINT_F -> { + val value = vm.registers.getFloat(0) + print(value) + } else -> TODO("syscall ${call.name}") } } diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index ace3df34c..88cbdeef2 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -231,7 +231,10 @@ class VirtualMachine(val memory: Memory, program: List) { } private fun InsLOAD(i: Instruction) { - setResultReg(i.reg1!!, i.value!!, i.type!!) + if(i.type==VmDataType.FLOAT) + registers.setFloat(i.fpReg1!!, i.fpValue!!) + else + setResultReg(i.reg1!!, i.value!!, i.type!!) pc++ }