mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
refactor IR returnregs
This commit is contained in:
parent
c12bf991b3
commit
1fdee861e8
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user