refactor IR returnregs

This commit is contained in:
Irmen de Jong 2023-03-13 00:32:48 +01:00
parent c12bf991b3
commit 1fdee861e8
4 changed files with 1044 additions and 786 deletions

View File

@ -142,13 +142,15 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
// calculate the assignment value
if (vmDt == IRDataType.FLOAT) {
resultFpRegister = codeGen.registers.nextFreeFloat()
result += expressionEval.translateExpression(assignment.value, -1, resultFpRegister)
val tr = expressionEval.translateExpression(assignment.value, -1, resultFpRegister)
addToResult(result, tr, -1, resultFpRegister)
} else {
resultRegister = if (assignment.value is PtMachineRegister) {
(assignment.value as PtMachineRegister).register
} else {
val reg = codeGen.registers.nextFree()
result += expressionEval.translateExpression(assignment.value, reg, -1)
val tr = expressionEval.translateExpression(assignment.value, reg, -1)
addToResult(result, tr, reg, -1)
reg
}
}
@ -176,7 +178,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
if(array.index.type!=DataType.UBYTE)
throw AssemblyError("non-array var indexing requires bytes index")
val idxReg = codeGen.registers.nextFree()
result += expressionEval.translateExpression(array.index, idxReg, -1)
val tr = expressionEval.translateExpression(array.index, idxReg, -1)
addToResult(result, tr, idxReg, -1)
val code = IRCodeChunk(null, null)
if(zero) {
// there's no STOREZIX instruction
@ -232,7 +235,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
result += chunk
} else {
val addressReg = codeGen.registers.nextFree()
result += expressionEval.translateExpression(memory.address, addressReg, -1)
val tr = expressionEval.translateExpression(memory.address, addressReg, -1)
addToResult(result, tr, addressReg, -1)
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREZI, vmDt, reg1=addressReg) }
}
} else {
@ -241,7 +245,8 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
result += chunk
} else {
val addressReg = codeGen.registers.nextFree()
result += expressionEval.translateExpression(memory.address, addressReg, -1)
val tr = expressionEval.translateExpression(memory.address, addressReg, -1)
addToResult(result, tr, addressReg, -1)
result += IRCodeChunk(null, null).also { it += IRInstruction(Opcode.STOREI, vmDt, reg1=resultRegister, reg2=addressReg) }
}
}
@ -253,7 +258,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
}
private fun loadIndexReg(array: PtArrayIndexer, itemsize: Int, indexReg: Int): IRCodeChunks {
return if(itemsize==1) {
val tr = if(itemsize==1) {
expressionEval.translateExpression(array.index, indexReg, -1)
} else {
val mult = PtBinaryExpression("*", DataType.UBYTE, array.position)
@ -261,5 +266,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
mult.children += PtNumber(DataType.UBYTE, itemsize.toDouble(), array.position)
expressionEval.translateExpression(mult, indexReg, -1)
}
require(tr.resultReg==indexReg && tr.resultFpReg==-1) // TODO weg
return tr.chunks
}
}

View File

@ -9,48 +9,113 @@ import prog8.intermediate.*
internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGen: ExpressionGen) {
fun translate(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
return when(call.name) {
"any" -> funcAny(call, resultRegister)
"all" -> funcAll(call, resultRegister)
"abs" -> funcAbs(call, resultRegister)
"cmp" -> funcCmp(call)
"sgn" -> funcSgn(call, resultRegister)
"sqrt16" -> funcSqrt16(call, resultRegister)
"pop" -> funcPop(call)
"popw" -> funcPopw(call)
"push" -> funcPush(call)
"pushw" -> funcPushw(call)
fun translate(call: PtBuiltinFunctionCall): ExpressionCodeResult {
when(call.name) {
"any" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcAny(call, resultRegister), IRDataType.BYTE, resultRegister, -1)
}
"all" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcAll(call, resultRegister), IRDataType.BYTE, resultRegister, -1)
}
"abs" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcAbs(call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
}
"cmp" -> {
return ExpressionCodeResult(funcCmp(call), codeGen.irType(call.args[0].type), -1, -1)
}
"sgn" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcSgn(call, resultRegister), codeGen.irType(call.type), resultRegister, -1)
}
"sqrt16" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcSqrt16(call, resultRegister), IRDataType.WORD, resultRegister, -1)
}
"pop" -> {
return ExpressionCodeResult(funcPop(call), IRDataType.BYTE, -1, -1)
}
"popw" -> {
return ExpressionCodeResult(funcPopw(call), IRDataType.WORD, -1, -1)
}
"push" -> {
return ExpressionCodeResult(funcPush(call), IRDataType.BYTE, -1, -1)
}
"pushw" -> {
return ExpressionCodeResult(funcPushw(call), IRDataType.BYTE,-1, -1)
}
"rsave",
"rsavex",
"rrestore",
"rrestorex" -> emptyList() // vm doesn't have registers to save/restore
"rrestorex" -> {
return ExpressionCodeResult.EMPTY // vm doesn't have registers to save/restore
}
"callfar" -> throw AssemblyError("callfar() is for cx16 target only")
"msb" -> funcMsb(call, resultRegister)
"lsb" -> funcLsb(call, resultRegister)
"memory" -> funcMemory(call, resultRegister)
"peek" -> funcPeek(call, resultRegister)
"peekw" -> funcPeekW(call, resultRegister)
"poke" -> funcPoke(call)
"pokew" -> funcPokeW(call)
"pokemon" -> emptyList()
"mkword" -> funcMkword(call, resultRegister)
"sort" -> funcSort(call)
"reverse" -> funcReverse(call)
"rol" -> funcRolRor(Opcode.ROXL, call, resultRegister)
"ror" -> funcRolRor(Opcode.ROXR, call, resultRegister)
"rol2" -> funcRolRor(Opcode.ROL, call, resultRegister)
"ror2" -> funcRolRor(Opcode.ROR, call, resultRegister)
"msb" -> return funcMsb(call)
"lsb" -> return funcLsb(call)
"memory" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcMemory(call, resultRegister), IRDataType.WORD, resultRegister, -1)
}
"peek" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcPeek(call, resultRegister), IRDataType.BYTE, resultRegister, -1)
}
"peekw" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcPeekW(call, resultRegister), IRDataType.WORD, resultRegister, -1)
}
"poke" -> {
return ExpressionCodeResult(funcPoke(call), IRDataType.BYTE, -1, -1)
}
"pokew" -> {
return ExpressionCodeResult(funcPokeW(call), IRDataType.BYTE,-1, -1)
}
"pokemon" -> {
return ExpressionCodeResult(emptyList(), IRDataType.BYTE, -1, -1)
}
"mkword" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcMkword(call, resultRegister), IRDataType.WORD, resultRegister, -1)
}
"sort" -> {
return ExpressionCodeResult(funcSort(call), IRDataType.BYTE, -1, -1)
}
"reverse" -> {
return ExpressionCodeResult(funcReverse(call), IRDataType.BYTE, -1, -1)
}
"rol" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcRolRor(Opcode.ROXL, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
}
"ror" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcRolRor(Opcode.ROXR, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
}
"rol2" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcRolRor(Opcode.ROL, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
}
"ror2" -> {
val resultRegister = codeGen.registers.nextFree()
return ExpressionCodeResult(funcRolRor(Opcode.ROR, call, resultRegister), codeGen.irType(call.args[0].type), resultRegister, -1)
}
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
}
}
// TODO let all funcs return ExpressionCodeResult as well
private fun funcCmp(call: PtBuiltinFunctionCall): IRCodeChunks {
val leftRegister = codeGen.registers.nextFree()
val rightRegister = codeGen.registers.nextFree()
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], leftRegister, -1)
result += exprGen.translateExpression(call.args[1], rightRegister, -1)
var tr = exprGen.translateExpression(call.args[0], leftRegister, -1)
addToResult(result, tr, leftRegister, -1)
tr = exprGen.translateExpression(call.args[1], rightRegister, -1)
addToResult(result, tr, rightRegister, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.CMP, codeGen.irType(call.args[0].type), reg1=leftRegister, reg2=rightRegister)
}
@ -70,7 +135,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
else -> throw IllegalArgumentException("weird type")
}
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
val tr = exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
@ -93,7 +159,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
else -> throw IllegalArgumentException("weird type")
}
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
val tr = exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
@ -107,7 +174,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val sourceDt = call.args.single().type
val result = mutableListOf<IRCodeChunkBase>()
if(sourceDt!=DataType.UWORD) {
result += exprGen.translateExpression(call.args[0], resultRegister, -1)
val tr = exprGen.translateExpression(call.args[0], resultRegister, -1)
addToResult(result, tr, resultRegister, -1)
when (sourceDt) {
DataType.UBYTE -> {
result += IRCodeChunk(null, null).also {
@ -146,7 +214,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcSgn(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
val reg = codeGen.registers.nextFree()
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args.single(), reg, -1)
val tr = exprGen.translateExpression(call.args.single(), reg, -1)
addToResult(result, tr, reg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.SGN, codeGen.irType(call.type), reg1 = resultRegister, reg2 = reg)
}
@ -156,7 +225,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcSqrt16(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
val reg = codeGen.registers.nextFree()
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args.single(), reg, -1)
val tr = exprGen.translateExpression(call.args.single(), reg, -1)
addToResult(result, tr, reg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.SQRT, IRDataType.WORD, reg1=resultRegister, reg2=reg)
}
@ -184,7 +254,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcPush(call: PtBuiltinFunctionCall): IRCodeChunks {
val result = mutableListOf<IRCodeChunkBase>()
val reg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args.single(), reg, -1)
val tr = exprGen.translateExpression(call.args.single(), reg, -1)
addToResult(result, tr, reg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=reg)
}
@ -194,7 +265,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcPushw(call: PtBuiltinFunctionCall): IRCodeChunks {
val result = mutableListOf<IRCodeChunkBase>()
val reg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args.single(), reg, -1)
val tr = exprGen.translateExpression(call.args.single(), reg, -1)
addToResult(result, tr, reg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = reg)
}
@ -212,7 +284,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
else -> throw IllegalArgumentException("weird type to reverse")
}
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
val tr = exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
@ -234,7 +307,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
else -> throw IllegalArgumentException("weird type to sort")
}
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
val tr = exprGen.translateExpression(call.args[0], SyscallRegisterBase, -1)
addToResult(result, tr, SyscallRegisterBase, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = SyscallRegisterBase+1, value = array.length)
it += IRInstruction(Opcode.SYSCALL, value = syscall.number)
@ -245,8 +319,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
private fun funcMkword(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
val msbReg = codeGen.registers.nextFree()
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], msbReg, -1)
result += exprGen.translateExpression(call.args[1], resultRegister, -1)
var tr = exprGen.translateExpression(call.args[0], msbReg, -1)
addToResult(result, tr, msbReg, -1)
tr = exprGen.translateExpression(call.args[1], resultRegister, -1)
addToResult(result, tr, resultRegister, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.CONCAT, IRDataType.BYTE, reg1 = resultRegister, reg2 = msbReg)
}
@ -263,7 +339,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
} else {
val addressReg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args[0], addressReg, -1)
val tr = exprGen.translateExpression(call.args[0], addressReg, -1)
addToResult(result, tr, addressReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREZI, IRDataType.WORD, reg1 = addressReg)
}
@ -272,14 +349,17 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val valueReg = codeGen.registers.nextFree()
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
result += exprGen.translateExpression(call.args[1], valueReg, -1)
val tr = exprGen.translateExpression(call.args[1], valueReg, -1)
addToResult(result, tr, valueReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREM, IRDataType.WORD, reg1 = valueReg, value = address)
}
} else {
val addressReg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args[0], addressReg, -1)
result += exprGen.translateExpression(call.args[1], valueReg, -1)
var tr = exprGen.translateExpression(call.args[0], addressReg, -1)
addToResult(result, tr, addressReg, -1)
tr = exprGen.translateExpression(call.args[1], valueReg, -1)
addToResult(result, tr, valueReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREI, IRDataType.WORD, reg1 = valueReg, reg2 = addressReg)
}
@ -298,7 +378,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
} else {
val addressReg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args[0], addressReg, -1)
val tr = exprGen.translateExpression(call.args[0], addressReg, -1)
addToResult(result, tr, addressReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREZI, IRDataType.BYTE, reg1 = addressReg)
}
@ -307,14 +388,17 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
val valueReg = codeGen.registers.nextFree()
if (call.args[0] is PtNumber) {
val address = (call.args[0] as PtNumber).number.toInt()
result += exprGen.translateExpression(call.args[1], valueReg, -1)
val tr = exprGen.translateExpression(call.args[1], valueReg, -1)
addToResult(result, tr, valueReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREM, IRDataType.BYTE, reg1 = valueReg, value = address)
}
} else {
val addressReg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args[0], addressReg, -1)
result += exprGen.translateExpression(call.args[1], valueReg, -1)
var tr = exprGen.translateExpression(call.args[0], addressReg, -1)
addToResult(result, tr, addressReg, -1)
tr = exprGen.translateExpression(call.args[1], valueReg, -1)
addToResult(result, tr, valueReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.STOREI, IRDataType.BYTE, reg1 = valueReg, reg2 = addressReg)
}
@ -332,7 +416,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
} else {
val addressReg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args.single(), addressReg, -1)
val tr = exprGen.translateExpression(call.args.single(), addressReg, -1)
addToResult(result, tr, addressReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADI, IRDataType.WORD, reg1 = resultRegister, reg2 = addressReg)
}
@ -349,7 +434,8 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
}
} else {
val addressReg = codeGen.registers.nextFree()
result += exprGen.translateExpression(call.args.single(), addressReg, -1)
val tr = exprGen.translateExpression(call.args.single(), addressReg, -1)
addToResult(result, tr, addressReg, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOADI, IRDataType.BYTE, reg1 = resultRegister, reg2 = addressReg)
}
@ -364,25 +450,29 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
return listOf(code)
}
private fun funcLsb(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
private fun funcLsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val resultRegister = codeGen.registers.nextFree()
return 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.
}
private fun funcMsb(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
private fun funcMsb(call: PtBuiltinFunctionCall): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args.single(), resultRegister, -1)
val resultRegister = codeGen.registers.nextFree()
val tr = exprGen.translateExpression(call.args.single(), resultRegister, -1)
addToResult(result, tr, resultRegister, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.MSIG, IRDataType.BYTE, reg1 = resultRegister, reg2 = resultRegister)
}
// note: if a word result is needed, the upper byte is cleared by the typecast that follows. No need to do it here.
return result
return ExpressionCodeResult(result, IRDataType.BYTE, resultRegister, -1)
}
private fun funcRolRor(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks {
val vmDt = codeGen.irType(call.args[0].type)
val result = mutableListOf<IRCodeChunkBase>()
result += exprGen.translateExpression(call.args[0], resultRegister, -1)
val tr = exprGen.translateExpression(call.args[0], resultRegister, -1)
addToResult(result, tr, resultRegister, -1)
result += IRCodeChunk(null, null).also {
it += IRInstruction(opcode, vmDt, reg1 = resultRegister)
}

View File

@ -238,8 +238,15 @@ class IRCodeGen(
is PtAssignment -> assignmentGen.translate(node)
is PtAugmentedAssign -> assignmentGen.translate(node)
is PtNodeGroup -> translateGroup(node.children)
is PtBuiltinFunctionCall -> translateBuiltinFunc(node, 0)
is PtFunctionCall -> expressionEval.translate(node, 0, 0)
is PtBuiltinFunctionCall -> {
val result = translateBuiltinFunc(node)
result.chunks // it's not an expression so no result value.
}
is PtFunctionCall -> {
val result = expressionEval.translate(node, 0, 0)
require(result.resultReg==0 && result.resultFpReg==0) // TODO weg
result.chunks
}
is PtNop -> emptyList()
is PtReturn -> translate(node)
is PtJump -> translate(node)
@ -398,7 +405,8 @@ class IRCodeGen(
val valueReg = registers.nextFree()
val choiceReg = registers.nextFree()
val valueDt = irType(whenStmt.value.type)
result += expressionEval.translateExpression(whenStmt.value, valueReg, -1)
val tr = expressionEval.translateExpression(whenStmt.value, valueReg, -1)
addToResult(result, tr, valueReg, -1)
val choices = whenStmt.choices.children.map {it as PtWhenChoice }
val endLabel = createLabelName()
for (choice in choices) {
@ -523,8 +531,10 @@ class IRCodeGen(
val loopLabel = createLabelName()
val result = mutableListOf<IRCodeChunkBase>()
result += expressionEval.translateExpression(iterable.to, endvalueReg, -1)
result += expressionEval.translateExpression(iterable.from, indexReg, -1)
var tr = expressionEval.translateExpression(iterable.to, endvalueReg, -1)
addToResult(result, tr, endvalueReg, -1)
tr = expressionEval.translateExpression(iterable.from, indexReg, -1)
addToResult(result, tr, indexReg, -1)
val labelAfterFor = createLabelName()
val greaterOpcode = if(loopvarDt in SignedDatatypes) Opcode.BGTS else Opcode.BGT
@ -909,8 +919,10 @@ class IRCodeGen(
val leftFpRegNum = registers.nextFreeFloat()
val rightFpRegNum = registers.nextFreeFloat()
val compResultReg = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, -1, leftFpRegNum)
result += expressionEval.translateExpression(ifElse.condition.right, -1, rightFpRegNum)
var tr = expressionEval.translateExpression(ifElse.condition.left, -1, leftFpRegNum)
addToResult(result, tr, -1, leftFpRegNum)
tr = expressionEval.translateExpression(ifElse.condition.right, -1, rightFpRegNum)
addToResult(result, tr, -1, rightFpRegNum)
result += IRCodeChunk(null,null).also {
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftFpRegNum, fpReg2 = rightFpRegNum)
val gotoOpcode = when (ifElse.condition.operator) {
@ -932,8 +944,10 @@ class IRCodeGen(
} else {
val leftRegNum = registers.nextFree()
val rightRegNum = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, leftRegNum, -1)
result += expressionEval.translateExpression(ifElse.condition.right, rightRegNum, -1)
var tr = expressionEval.translateExpression(ifElse.condition.left, leftRegNum, -1)
addToResult(result, tr, leftRegNum, -1)
tr = expressionEval.translateExpression(ifElse.condition.right, rightRegNum, -1)
addToResult(result, tr, rightRegNum, -1)
val opcode: Opcode
val firstReg: Int
val secondReg: Int
@ -992,7 +1006,8 @@ class IRCodeGen(
val leftFpReg = registers.nextFreeFloat()
val rightFpReg = registers.nextFreeFloat()
compResultReg = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, -1, leftFpReg)
val tr = expressionEval.translateExpression(ifElse.condition.left, -1, leftFpReg)
addToResult(result, tr, -1, leftFpReg)
result += IRCodeChunk(null, null).also {
it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, fpValue = 0f)
it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftFpReg, fpReg2 = rightFpReg)
@ -1010,7 +1025,8 @@ class IRCodeGen(
// integer comparisons
branchDt = irDtLeft
compResultReg = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, compResultReg, -1)
val tr = expressionEval.translateExpression(ifElse.condition.left, compResultReg, -1)
addToResult(result, tr, compResultReg, -1)
elseBranch = when (ifElse.condition.operator) {
"==" -> Opcode.BNZ
"!=" -> Opcode.BZ
@ -1049,12 +1065,13 @@ class IRCodeGen(
val elseBranchSecondReg: Int
val branchDt: IRDataType
if(irDtLeft==IRDataType.FLOAT) {
branchDt = IRDataType.BYTE
val leftFpRegNum = registers.nextFreeFloat()
val rightFpRegNum = registers.nextFreeFloat()
val compResultReg = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, -1, leftFpRegNum)
result += expressionEval.translateExpression(ifElse.condition.right, -1, rightFpRegNum)
var tr = expressionEval.translateExpression(ifElse.condition.left, -1, leftFpRegNum)
addToResult(result, tr, -1, leftFpRegNum)
tr = expressionEval.translateExpression(ifElse.condition.right, -1, rightFpRegNum)
addToResult(result, tr, -1, rightFpRegNum)
addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftFpRegNum, fpReg2 = rightFpRegNum), null)
val elseBranch = when (ifElse.condition.operator) {
"==" -> Opcode.BNZ
@ -1086,8 +1103,10 @@ class IRCodeGen(
branchDt = irDtLeft
val leftRegNum = registers.nextFree()
val rightRegNum = registers.nextFree()
result += expressionEval.translateExpression(ifElse.condition.left, leftRegNum, -1)
result += expressionEval.translateExpression(ifElse.condition.right, rightRegNum, -1)
var tr = expressionEval.translateExpression(ifElse.condition.left, leftRegNum, -1)
addToResult(result, tr, leftRegNum, -1)
tr = expressionEval.translateExpression(ifElse.condition.right, rightRegNum, -1)
addToResult(result, tr, rightRegNum, -1)
when (ifElse.condition.operator) {
"==" -> {
elseBranchOpcode = Opcode.BNE
@ -1178,7 +1197,8 @@ class IRCodeGen(
} else {
val incReg = registers.nextFree()
val addressReg = registers.nextFree()
result += expressionEval.translateExpression(memory.address, addressReg, -1)
val tr = expressionEval.translateExpression(memory.address, addressReg, -1)
addToResult(result, tr, addressReg, -1)
val chunk = IRCodeChunk(null, null)
chunk += IRInstruction(Opcode.LOADI, irDt, reg1 = incReg, reg2 = addressReg)
chunk += IRInstruction(operationRegister, irDt, reg1 = incReg)
@ -1195,7 +1215,8 @@ class IRCodeGen(
} else {
val incReg = registers.nextFree()
val indexReg = registers.nextFree()
result += expressionEval.translateExpression(array.index, indexReg, -1)
val tr = expressionEval.translateExpression(array.index, indexReg, -1)
addToResult(result, tr, indexReg, -1)
val chunk = IRCodeChunk(null, null)
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexReg, labelSymbol=variable)
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
@ -1223,7 +1244,8 @@ class IRCodeGen(
val counterReg = registers.nextFree()
val irDt = irType(repeat.count.type)
val result = mutableListOf<IRCodeChunkBase>()
result += expressionEval.translateExpression(repeat.count, counterReg, -1)
val tr = expressionEval.translateExpression(repeat.count, counterReg, -1)
addToResult(result, tr, counterReg, -1)
addInstr(result, IRInstruction(Opcode.BZ, irDt, reg1=counterReg, labelSymbol = skipRepeatLabel), null)
result += labelFirstChunk(translateNode(repeat.statements), repeatLabel)
val chunk = IRCodeChunk(null, null)
@ -1264,12 +1286,14 @@ class IRCodeGen(
} else {
if(value.type==DataType.FLOAT) {
val reg = registers.nextFreeFloat()
result += expressionEval.translateExpression(value, -1, reg)
val tr = expressionEval.translateExpression(value, -1, reg)
addToResult(result, tr, -1, reg)
addInstr(result, IRInstruction(Opcode.RETURNREG, IRDataType.FLOAT, fpReg1 = reg), null)
}
else {
val reg = registers.nextFree()
result += expressionEval.translateExpression(value, reg, -1)
val tr = expressionEval.translateExpression(value, reg, -1)
addToResult(result, tr, reg, -1)
addInstr(result, IRInstruction(Opcode.RETURNREG, irType(value.type) , reg1=reg), null)
}
}
@ -1363,8 +1387,8 @@ class IRCodeGen(
return "prog8_label_gen_$labelSequenceNumber"
}
internal fun translateBuiltinFunc(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunks =
builtinFuncGen.translate(call, resultRegister)
internal fun translateBuiltinFunc(call: PtBuiltinFunctionCall): ExpressionCodeResult
= builtinFuncGen.translate(call)
internal fun isZero(expression: PtExpression): Boolean = expression is PtNumber && expression.number==0.0