vm: implementing floating-point

This commit is contained in:
Irmen de Jong 2022-04-29 22:27:02 +02:00
parent f4993d6e5d
commit 7844ace934
14 changed files with 211 additions and 152 deletions

View File

@ -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}")
}
}

View File

@ -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 -> {

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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() {

View File

@ -125,6 +125,7 @@ private val functionSignatures: List<FSignature> = 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),
)

View File

@ -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)

View File

@ -8,6 +8,7 @@
main {
sub start() {
txt.print("float tests: ")
float f1 = 1.2345
float f2 = -9.99
float f3

View File

@ -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))
}
}

View File

@ -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}")
}
}

View File

@ -231,7 +231,10 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
}
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++
}